Models
You can find the model component in the toolbar under Gorilla3D > TGorillaModel
A TGorillaModel component automatically manages sub-meshes, materials and animations for you. So this is the best component for loading complex mesh data.
Every model contains a number of TGorillaMesh instances which holds the vertex data of a specific child mesh. At least one mesh will be available in a valid model.
When loading models from file / stream, all materials, animations, lights and cameras, defined in the source file / stream, are loaded too. In case you are using explicit animation files (only for DAE and FBX format), you need to load them afterwards by AddAnimationFromFile().
A TGorillaModel instance needs to be a child / sub-child of a TGorillaViewport instance, otherwise it will not be displayed.
Tutorial
Supported file formats
Currently it is allowed to use the following file-formats:
Format | MeshData | Materials | Animations | Lights | Cameras | Physics | Shaders | Export | Version | Notice |
---|---|---|---|---|---|---|---|---|---|---|
G3D | ✔ | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✔ | 1, 2 | |
DAE | ✔ | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ | 1.4+ | |
FBX | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | 7.1 - 7.7 | only binary format, animation import for 7.3 - 7.7 |
glTF/GLB | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | 2.0 | only glTF 2.0 format |
OBJ | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | only ascii format | |
STL | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | 1.0 | ascii and binary format, Standard + Solidworks-Format |
X3D | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | deprecated | |
Babylon | ✔ | ✔ | ✘ | ✔ | ✘ | ✘ | ✘ | ✘ | 4.x | |
Sketchfab | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | glTF 2.0 | |
PLY | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | 1.0 | ascii and binary format (since v0.8.3.1966+) |
SketchUp | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | v2020 | only Win64 binaries available (since v0.8.3.1966+) |
The framework offers various ways to load model data into your project. Basically you need to decide when to load the data.
Design-Time
It is possible to load model data at design time in the IDE form editor. Simple drop a TGorillaModel from component palette onto your form.
The component should be placed inside a TGorillaViewport component or as child of another component inside the viewport.
You have the choice between embedding your model in the formular data (*.fmx file) or loading it dynamically from an assets package.
Embedded Model
Embedding models will store complete model data with hierarchy, animations, materials and textures into binary storage inside of your formular *.fmx file. The framework is able to load that data again.
Use the following steps:
- Drop a TGorillaModel component into your viewport
- Choose the “Source” property in the object inspector and open its dialog by “[…]”
- Select your model file (Please check the supported file formats!)
- An options dialog will open to configure your loading options
- All model data will be stored inside the *.fmx file of your form
When the loading options dialog appears you can configure the import process. But not all options are available for all formats.
- Ignore importing animations
- Animation caching settings
- Ignore importing lights or cameras
- Directly import additional animation files without an extra call
- Limit texture size, in case you have a memory-sensitive application
Afterwards the IDE will show up a loading window while importing.
Because the data + textures are stored in the *.fmx of your form, it can become very large. This may slow down the performance of the IDE.
WARNING*: Your IDE memory is limited to 3GB, which can be exceeded very fast due to cached model data with textures.
Using Packages
To load model data from an assets package at design time, you will need a TGorillaAssetsManager component and a TGorillaModel component.
- Drop a TGorillaAssetsManager component onto your form
- Open the “Packages” collection
- Add a new package to the list
- Give it a DisplayName and a file location (during development we recommend a general location like “C:\Temp\assets.zip”)
- Drop a TGorillaModel component onto your viewport
- Link the TGorillaAssetsManager component to the TGorillaModel.AssetsManager property
- Type in the name of your package (DisplayName) into the “PackageName” property
- Type in the model asset name in your package into the “Source” property or load from disk
- If the package does not contain the model data yet, it will automatically add it to the archive
The IDE will show up a load-options dialog if the model data did not already exist.
If it was already available in the archive the IDE will show a loading-dialog while importing the data into cache.
Notice: The IDE will reload the model data from package on each refresh! So the loading window may appear multiple times during development.
The data is not stored again in the formular *.fmx file, it only restores it from package information.
WARNING*: Your IDE memory is limited to 3GB, which can be exceeded very fast due to cached model data.
Sketchfab Import
A great feature of Gorilla3D is the integrated Sketchfab support at design time, which can be accessed by the TGorillaPrefabManager component.
To take advantage of that feature:
- Drop a TGorillaPrefabManager component onto your form
- Select the component in structure view and right click onto it
- A popup menu appears with an “Import from Sketchfab” option.
- Another dialogue will open to search for your specific model
The plugin will download the model as glTF file from Sketchfab into:
C:\Users\Public\Documents\Gorilla3D\
Afterwards it will automatically create a new embedded TGorillaModel instance for you.
WARNING: We do not recommend to embed large models or models with many large textures. This will increase memory usage and size of DFM-data, which slows down the IDE!
NOTICE: Not all models on Sketchfab are fully compatible. The platform automatically converts models to glTF format, which sometimes destroys the model data.
WARNING: (2023-02-28) Due to some security issues we had to disable the Sketchfab plugin. We are sorry and we will try to fix the problem with the next update.
Runtime
Besides the user-friendly loading at design time, we of course support the model loading from file or stream.
Loading a new model from file
Creating a model instance at runtime is very easy and often very helpful for creating dynamically loaded scenes.
- Form1.pas
uses Gorilla.DefTypes, Gorilla.G3D.Loader, Gorilla.DAE.Loader, Gorilla.FBX.Loader, Gorilla.GLTF.Loader, Gorilla.GLB.Loader, Gorilla.OBJ.Loader, Gorilla.STL.Loader, Gorilla.Babylon.Loader, Gorilla.PLY.Loader, Gorilla.SKP.Loader, Gorilla.X3D.Loader, Gorilla.X3DZ.Loader, Gorilla.X3DVZ.Loader, Gorilla.Model; // in our form (TForm1) we added a field named "FModel" procedure TForm1.FormCreate(Sender: TObject); var LPath : String; LAssetPckg : TGorillaAssetPackage; begin LPath := 'c:\my3dfile.dae'; LAssetPckg := nil; FModel := TGorillaModel.LoadNewModelFromFile(FGorilla, LAssetPckg, OpenDialog1.FileName, GORILLA_ANIMATION_CACHING_DEFAULT); FModel.Parent := FGorilla; end;
For the moment you can ignore the last parameter “GORILLA_ANIMATION_CACHING_DEFAULT” of the LoadNewModelFromFile() call. We will explain this in the Animations section.
For loading model data from package, you need to setup an assets manager with a package item. You can then request a model file by its filename.
If the model data already exists, it will be loaded, otherwise it will be automatically added to the package.
- Form1.pas
uses Gorilla.DefTypes, Gorilla.G3D.Loader, Gorilla.DAE.Loader, Gorilla.FBX.Loader, Gorilla.GLTF.Loader, Gorilla.GLB.Loader, Gorilla.OBJ.Loader, Gorilla.STL.Loader, Gorilla.Babylon.Loader, Gorilla.PLY.Loader, Gorilla.SKP.Loader, Gorilla.X3D.Loader, Gorilla.X3DZ.Loader, Gorilla.X3DVZ.Loader, Gorilla.AssetsManager, Gorilla.Model; [...] var FAssetsManager : TGorillaAssetsManager; FPackage : TGorillaAssetsPackage; // in our form (TForm1) we added a field named "FModel" procedure TForm1.FormCreate(Sender: TObject); var LPath : String; LModel : TGorillaModel; begin // setup the assets manager and load an existing package from file FAssetsManager := TGorillaAssetsManager.Create(Self); FPackage := FAssetsManager.LoadPackageFromFile('C:\Temp\mypackage.zip'); FPackage.DisplayName := 'MyPackage'; // loading the model from package LPath := 'c:\my3dfile.dae'; LModel:= TGorillaModel.LoadNewModelFromFile(GorillaViewport1, FPackage {!}, LPath, GORILLA_ANIMATION_CACHING_DEFAULT); LModel.Parent := GorillaViewport1; end;
Loading into an existing TGorillaModel instance
In case you've dragged a TGorillaModel component onto your viewport, you can load the model by the following method. LoadFromFile() will remove previously created model data inside the instance before loading.
- Form1.pas
uses Gorilla.DefTypes, Gorilla.G3D.Loader, Gorilla.DAE.Loader, Gorilla.FBX.Loader, Gorilla.GLTF.Loader, Gorilla.GLB.Loader, Gorilla.OBJ.Loader, Gorilla.STL.Loader, Gorilla.Babylon.Loader, Gorilla.PLY.Loader, Gorilla.SKP.Loader, Gorilla.X3D.Loader, Gorilla.X3DZ.Loader, Gorilla.X3DVZ.Loader, Gorilla.Model; // in our form (TForm1) we added a field named "FModel" procedure TForm1.FormCreate(Sender: TObject); var LPath : String; LAssetPckg : TGorillaAssetPackage; begin LPath := 'c:\my3dfile.dae'; LAssetPckg := nil; GorillaModel1.LoadFromFile(LAssetPckg, OpenDialog1.FileName, GORILLA_ANIMATION_CACHING_DEFAULT); end;
To load a specific file format you need to include the intended format unit:
- Gorilla.G3D.Loader
- Gorilla.DAE.Loader
- Gorilla.FBX.Loader
- Gorilla.GLTF.Loader
- Gorilla.GLB.Loader
- Gorilla.OBJ.Loader
- Gorilla.STL.Loader
- Gorilla.Babylon.Loader
- Gorilla.Sketchfab.Loader (uses glTF format)
- Gorilla.X3D.Loader
- Gorilla.X3DZ.Loader
- Gorilla.X3DVZ.Loader
- Gorilla.PLY.Loader
- Gorilla.SKP.Loader
Only then the format loader is able to load the specific file.
The Better Loading
Configured loading is the better way of loading model data into your application at runtime.
It gives you the opportunity to tell the loader how to import data.
For example:
- You can choose to ignore importing lights or cameras
- You can directly import additional animation files without an extra call
- You can limit texture size, in case you have a memory-sensitive application
- You can define a status callback function (“TGorillaLoadingStatus = procedure(ALoader : TObject) of object;”)
- You can link to a specific model asset inside of package for fast model data reusage
Loading options can be submitted as argument to the LoadNewModelFromFile() or LoadFromFile() method.
In the following example we demonstrate the usage at runtime:
uses Gorilla.DefTypes, Gorilla.Model, Gorilla.FBX.Loader; [...] var LOpts : TGorillaLoadOptions; LMdlPath := IncludeTrailingPathDelimiter('C:\Temp\PACKAGETEST\ASSETS\Astronaut'); LOpts := TGorillaLoadOptions.Create(LMdlPath + 'Astronaut.fbx'); // only allow this exact filename and no automated lookup LOpts.FileInfo.StrictFilename := true; // link to a package and/or to a specific asset inside of a package LOpts.Package := nil; LOpts.Asset := nil; // limit to a max. size of textures (textures will be resized in aspect ratio) LOpts.TextureLimits := Point(512, 512); // ignore lights and camera for import LOpts.ImportLights := false; LOpts.ImportCameras := false; // user defined animation import LOpts.ImportAnimations := true; LOpts.AddAnimation(LMdlPath + 'Astronaut-idle.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-floating.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-hit.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-jump.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-punch-1.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-punch-2.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-walk-forward.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-walk-backward.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-walk-left.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-walk-right.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-run-forward.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-run-backward.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-run-left.fbx'); LOpts.AddAnimation(LMdlPath + 'Astronaut-run-right.fbx'); FModel := TGorillaModel.LoadNewModelFromFile(GorillaViewport1, LOpts); FModel.Parent := GorillaViewport1;
Loading a model from package source
To adopt the behaviour used in the IDE at design time, you can load model data from assets package also at runtime by the following method.
NOTICE: This will trigger design time dialogs on loading data. If you don't want that dialogs to appear, please use LoadNewModelFromFile() or LoadFromFile().
- Form1.pas
uses Gorilla.DefTypes, Gorilla.G3D.Loader, Gorilla.DAE.Loader, Gorilla.FBX.Loader, Gorilla.GLTF.Loader, Gorilla.GLB.Loader, Gorilla.OBJ.Loader, Gorilla.STL.Loader, Gorilla.Babylon.Loader, Gorilla.PLY.Loader, Gorilla.SKP.Loader, Gorilla.X3D.Loader, Gorilla.X3DZ.Loader, Gorilla.X3DVZ.Loader, Gorilla.AssetsManager, Gorilla.Model; [...] var FAssetsManager : TGorillaAssetsManager; FPackage : TGorillaAssetsPackage; FModel : TGorillaModel; // in our form (TForm1) we added a field named "FModel" procedure TForm1.FormCreate(Sender: TObject); begin // setup the assets manager and load an existing package from file FAssetsManager := TGorillaAssetsManager.Create(Self); FPackage := FAssetsManager.LoadPackageFromFile('C:\Temp\mypackage.zip'); FPackage.DisplayName := 'MyPackage'; // prepare the model for loading from package FModel := TGorillaModel.Create(GorillaViewport1); FModel.Parent := GorillaViewport1; // start linking to assets manager like at designtime FModel.AssetsManager := FAssetsManager; FModel.PackageName := 'MyPackage'; FModel.Source := 'myfile.dae'; end;
Loading a model from source
This is another way to load model data from file at runtime. The difference to LoadFromFile() and LoadNewModelFromFile() is, that it will store model data in the BinaryData property too.
- Form1.pas
uses Gorilla.DefTypes, Gorilla.G3D.Loader, Gorilla.DAE.Loader, Gorilla.OBJ.Loader, Gorilla.STL.Loader, Gorilla.FBX.Loader, Gorilla.GLTF.Loader, Gorilla.Babylon.Loader, Gorilla.PLY.Loader, Gorilla.SKP.Loader, Gorilla.AssetsManager, Gorilla.Model; [...] var FModel : TGorillaModel; // in our form (TForm1) we added a field named "FModel" procedure TForm1.FormCreate(Sender: TObject); begin // prepare the model for loading from package FModel := TGorillaModel.Create(GorillaViewport1); FModel.Parent := GorillaViewport1; FModel.Source := 'c:\Temp\myfile.dae'; end;
Sketchfab Runtime Support
Since 0.8.2.1675 we provide a Sketchfab plugin directly by using our loading mechanism. Before implementation you'll need to ensure you've got a valid Sketchfab account with username and password.
Remarks: You'll also need a new clientid and clientsecret for your application. To request those credentials contact support at https://sketchfab.com/developers/oauth#registering-your-app
The usage of the plugin is simular to other file formats in Gorilla3D. But instead of using the simple method headers, you'll have to use the extended method call with a TGorillaLoadOptions parameter.
// setup loading options to connect to sketchfab LOpts := TGorillaLoadOptions.Create(FUID, '.sketchfab', FPackage); LOpts.FileInfo.OpenFormat := TGorillaFileOpenFormat.fofDownload; LOpts.FileInfo.URL := Gorilla.Sketchfab.Loader.GORILLA_SKETCHFAB_URL; LOpts.FileInfo.ClientId := <YOUR_CLIENT_ID>; LOpts.FileInfo.ClientSecret := <YOUR_CLIENT_SECRET>; LOpts.FileInfo.Username := <YOUR_USERNAME>; LOpts.FileInfo.Password := <YOUR_PASSWORD>; // set an individual download folder, where data is written to // leave empty to use system temporary folders LOpts.ExtractDirectory := ''; try // try loading sketchfab model FModel := TGorillaModel.LoadNewModelFromFile(GorillaViewport1, LOpts); if Assigned(FModel) then FModel.Parent := GorillaViewport1; except on E:Exception do ShowMessage('Failed to load Sketchfab model: ' + E.Message); end;
The plugin will automatically download a zip-archive with a glTF file to your preferred folder (“ExtractDirectory”). On successful download it extracts this data and tries to load the contained model. Before requesting Sketchfab, the loader checks the ExtractDirectory for an already existing download of UID. If a zip and gltf file already exists it will directly load it, instead of downloading again.
You have to take care yourself in case a previous download is invalid or decprecated.
Components
Because model files mostly do not only contain a single element, but instead a complex hierarchy, we do provide various components to allow those structures.
TGorillaModel
A TGorillaModel is the “head” component for loaded models from file, stream or asset. Even it's inherited from TGorillaMesh, it's not renderable. Instead it is just a container, managing sub-meshes, animations and materials. So a TGorillaModel needs to contain at least one TGorillaMesh in it's Meshes list.
TGorillaMesh
A TGorillaMesh is visual representation for geometry data allowing to render shapes. It can contain further sub-meshes. Each TGorillaMesh can be rendered by a different TMaterialSource. It is allowed to use TGorillaMesh as standalone component for rendering (without a parent TGorillaModel). This is already used in our primitives: TGorillaCube, TGorillaSphere and so on. You need to create at least a TMeshDef instance for the “Def” property.
constructor TMyMesh.Create(AOwner: TComponent); begin inherited; // create a logical mesh definition instance FDef := TMeshDef.Create(nil); RebuildMesh(); end; procedure TMyMesh.RebuildMesh(AIsStatic : Boolean = true); begin // setup vertex and index data here [...] // push mesh data to our mesh-definition and create a static GPU buffer if AIsStatic then CreateStaticBuffer(); end; procedure TMyMesh.CreateStaticBuffer(); var LMeshDef : TMeshDef; LMeshData : TMeshData; begin LMeshDef := TMeshDef(FDef); LMeshDef.IsStatic := false; try LMeshData := Self.MeshData; // update rendering list and bounding box LMeshData.BoundingBoxNeedsUpdate(); LMeshData.GetBoundingBox(); DoUpdateParentRenderList(Parent); // copy vertices to mesh definition LMeshDef.ApplyFromMeshData(LMeshData); LMeshData.VertexBuffer.Length := 0; LMeshData.IndexBuffer.Length := 0; finally // we need to reset the "IsStatic" value to create a buffer object LMeshDef.IsStatic := true; end; end;
TGorillaVertexGroup
A TGorillaVertexGroup is inherited from TGorillaMesh, but renders differently. A vertex group allows to group a number of triangles, referred in an owner mesh, to a virtual mesh.
You are able to render only this specific triangle group by a specific material. To setup a vertex group you need to have separated indexbuffer in you MeshData and a parent mesh with corresponding vertex data.
In some cases this helps to improve memory usage. While declaring vertex data in a parent mesh, those virtual meshes can reuse the same vertices for their triangle rendering, instead of duplicating them.
CAUTION: TGorillaVertexGroup needs to be attached to an owner TGorillaMesh as child, with the relevant vertex data.
WARNING: Currently it is not recommended to setup a TGorillaVertexGroup yourself. Instead use the definition hierarchy by TVertexGroupDef inside of TMeshDef. By TGorillaModel.LoadNewModelFromDef() you are able to build visual components from your definitions.
TGorillaGroup
A TGorillaGroup is just a simple transformable element used to group sub-meshes. A group itself is not renderable.
Instancing / Cloning
Instanced Rendering
Since 0.8.3.2265 instanced rendering of the same mesh for x-times was implemented.
Use this method to render for example grass or trees. It is not recommended to use it for animated charaters, because they would be rendered the same (with the same animation frame).
At DesignTime
We offer a collection property called “Instances” in the TGorillaModel/TGorillaMesh component.
You can simply add instances at design time with their transformation information.
NOTICE: The transformation information (position, rotation and scale) is absolute and not depending on the owner mesh.
At Runtime
For better usability TGorillaMesh/TGorillaModel components provide the collection property “Instances”. Internally it will be cached in buffer for fast GPU transmission.
This brings new opportunities, especially for instancing a very large number, f.e. you don't want to setup a single TCollectionItem to render 100.000 grass blades.
In that case you want to ignore the collection and simply add those instances to the buffer. Therefore please use the AddInstance() method
function AddInstance(const ATransform : TMatrix3D; const ACreateItem : Boolean; AName : String = '') : Integer;
/// we create 4 instances in a row GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(-10, 0, 0)), false); GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(-5, 0, 0)), false); GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(5, 0, 0)), false); GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(10, 0, 0)), false); /// afterwards we can modify a specific instance var LTransf : TMatrix3D; LTransf := TMatrix3D.CreateScaling(Point3D(2, 2, 2)); LTransf := LTransf * TMatrix3D.CreateRotationY(DegToRad(90)); LTransf := LTransf * TMatrix3D.CreateScaling(Point3D(2, 2, 2)); GorillaModel1.Instances[2] := LTransf;
WARNING: Only use one of the functionalities: Collection / Buffering. When adding collection items again, the instance buffer will be refreshed and previously added instances will be cleared.
Cloning
Instancing can be done by GPU and providing different transformation matrices like above or by cloning the visual component with all of it's data. Both ways have their advantages and disadvantages.
- Use instancing if you want to re-render a mesh multiple times
- Use cloning if you need different visual feedback (like animations or materials), but if you want to reuse the vertex data itself
In the following example we show how to load a complex animated model with multiple meshes and animations. We will load up a template (TModelDef), which will be used for duplication. The template (TModelDef) itself will not be rendered in our example, but of course that's possible too.
Each duplicated model will run a different animation to show instanciating is still fast, but allows to handle models differently. This demo code uses cached animations (GORILLA_ANIMATION_CACHING_DEFAULT), otherwise 32 animated instances will not render properly anymore, due to many vertex operations.
procedure TForm1.InstanciateModel(AModelsPath : String); const NUM_OF_MODELS = 32; MODELS_SPACE = 8; var LAnim : TGorillaAnimation; LMdlPath : String; I : Integer; LPlayInst : TGorillaModel; LOfs : Single; begin LAnim := nil; // load player model LMdlPath := IncludeTrailingPathDelimiter(AModelsPath) + IncludeTrailingPathDelimiter('archer'); FPlayerTemplate := TGorillaModel.LoadNewModelFromFile(FGorilla, FPackage, LMdlPath + 'archer.dae', GORILLA_ANIMATION_CACHING_DEFAULT); FPlayerTemplate.Parent := FGorilla; FPlayerTemplate.Scale.Point := Point3D(0.05, 0.05, 0.05); FPlayerTemplate.SetHitTestValue(false); // add various animations FPlayerTemplate.AddAnimationFromFile(LMdlPath + 'archer-aim-idle.dae', GORILLA_ANIMATION_CACHING_DEFAULT); FPlayerTemplate.AddAnimationFromFile(LMdlPath + 'archer-idle2.dae', GORILLA_ANIMATION_CACHING_DEFAULT); FPlayerTemplate.AddAnimationFromFile(LMdlPath + 'archer-idle3.dae', GORILLA_ANIMATION_CACHING_DEFAULT); FPlayerTemplate.AddAnimationFromFile(LMdlPath + 'archer-crouch-idle.dae', GORILLA_ANIMATION_CACHING_DEFAULT); // now create instances FPlayerInstances := TObjectList<TGorillaModel>.Create(false); I := 0; for I := 0 to NUM_OF_MODELS - 1 do begin // perform a real duplication of visual components by **FALSE** for the second parameter // if second parameter is **TRUE**, only proxy components will be produced LPlayInst := FPlayerTemplate.Duplicate(FGorilla, false) as TGorillaModel; FPlayerInstances.Add(LPlayInst); LPlayInst.Parent := FGorilla; // line up characters in a row LOfs := -(NUM_OF_MODELS div 2) * MODELS_SPACE; LPlayInst.Position.Point := Point3D(LOfs + (I * MODELS_SPACE), 0, 0); LPlayInst.RotationAngle.X := 180; // select one of the available animations - so characters animate differently case I mod 4 of 0 : LAnim := LPlayInst.AnimationManager.Animations.Items['archer-aim-idle.dae']; 1 : LAnim := LPlayInst.AnimationManager.Animations.Items['archer-idle2.dae']; 2 : LAnim := LPlayInst.AnimationManager.Animations.Items['archer-idle3.dae']; else LAnim := LPlayInst.AnimationManager.Animations.Items['archer-crouch-idle.dae']; end; // start the duplicated character animation if Assigned(LAnim) then LAnim.Start(); end; // we ignore the template for rendering FPlayerTemplate.Visible := false; end;
Exporting a model
We provide 2 export formats at the moment: G3D and STL, which are easy to use.
G3D Export
uses Gorilla.G3D.Exporter; procedure TForm1.MenuItem1Click(Sender: TObject); var LG3DExp : TGorillaG3DExporter; LToBinary : Boolean; LZipped : Boolean; LBeautified : Boolean; begin LToBinary := true; LZipped := true; LBeautified := true; if Assigned(fModel) then begin if SaveDialog1.Execute() then begin LG3DExp := TGorillaG3DExporter.Create(); try if LToBinary then LG3DExp.Format := TGorillaG3DFormat.BSONFormat else LG3DExp.Format := TGorillaG3DFormat.JSONFormat; LG3DExp.Zipped := LZipped; LG3DExp.Beautified := LBeautified; LG3DExp.SaveToFile(fModel.Def as TModelDef, SaveDialog1.FileName); finally FreeAndNil(LG3DExp); end; ShowMessage('File successfully stored:'#13#10+ SaveDialog1.FileName); end; end; end;
STL Export
<file pascal> uses Gorilla.STL.Exporter; procedure TForm1.MenuItem1Click(Sender: TObject); var LSTLExp : TGorillaSTLExporter; LToBinary : Boolean; LAllowMultipleMeshes : Boolean; LUseMultipleFiles : Boolean; begin // ascii and binary format supported LToBinary := true; // because STL supports only single meshes per file (per default), // we can split up a model with multiple meshes into multiple files LAllowMultipleMeshes := true; // but this exporter also allows to export multiple meshes to a single file // just set UseMultipleFiles to false LUseMultipleFiles := true; if Assigned(FModel) then begin if SaveDialog1.Execute() then begin LSTLExp := TGorillaSTLExporter.Create(); try LSTLExp.Binary := LToBinary; LSTLExp.AllowMultipleMeshes := LAllowMultipleMeshes; LSTLExp.UseMultipleFiles := LUseMultipleFiles; LSTLExp.SaveToFile(FModel.Def as TModelDef, SaveDialog1.FileName); finally FreeAndNil(LSTLExp); end; ShowMessage('File successfully stored:'#13#10+ SaveDialog1.FileName); end; end; end;
OBJ Export
The OBJ exporter is capable of exporting multiple meshes and hierarchies into a *.obj file and to store material information in a separated *.mtl file.
The MTL file will automatically be stored at the same location as the *.obj file with the *.obj.mtl extension.
uses Gorilla.OBJ.Exporter; procedure TForm1.MenuItem1Click(Sender: TObject); var LOBJExp : TGorillaOBJExporter; begin if Assigned(FModel) then begin if SaveDialog1.Execute() then begin LOBJExp := TGorillaOBJExporter.Create(); try LOBJExp.SaveToFile(FModel.Def as TModelDef, SaveDialog1.FileName); finally FreeAndNil(LOBJExp); end; ShowMessage('File successfully stored:'#13#10+ SaveDialog1.FileName); end; end; end;
Next step: Animations