Warning: Undefined array key "translationlc" in /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php on line 237
Warning: Cannot modify header information - headers already sent by (output started at /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php:237) in /usr/www/users/fabook/_diggets/doc/v2/inc/Action/Export.php on line 104
Warning: Cannot modify header information - headers already sent by (output started at /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php:237) in /usr/www/users/fabook/_diggets/doc/v2/inc/Action/Export.php on line 104
Warning: Cannot modify header information - headers already sent by (output started at /usr/www/users/fabook/_diggets/doc/v2/lib/plugins/translation/action.php:237) in /usr/www/users/fabook/_diggets/doc/v2/inc/Action/Export.php on line 104
====== Loading 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 and animations, defined in the source file / stream, are loaded too.
In case you are using explicit animation files (only for Collada DAE 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.
===== 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+ | |
| OBJ | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | | only ascii format|
| STL | ✔ |✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | 1.0 | ascii and binary format, Standard + Solidworks-Format|
| FBX | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | 7.1 - 7.5 | only binary (v0.8.3.1931+). Animation import for 7.3-7.4 validated, 7.5 not working properly yet|
| X3D | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ | ✘ | ✘ | | deprecated |
| glTF | ✔ |✔ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | 2.0 | only glTF json format, not glb|
| 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+)|
===== 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/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.
===== Loading a models at designtime =====
Since v0.8.3.2265 Gorilla3D is able to load model in designtime editor.
We provide different ways to do it.
==== Loading a model from an assets package ====
In case you have already set up an assets package with the assets manager in your form, you can link a TGorillaModal to that.
- 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
The IDE will show up a loading window while it's setting up the model.
The framework will generate TGorillaModel data from the linked package. It will repeat to load the model when starting the application.
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 data by the IDE.
==== Loading a model from binary storage ====
It is also possible to store and load complete model data (incl. textures) from binary storage inside of your formular *.fmx file.
To do so, simply:
- Open the file dialog of the "Source" property in the object inspector
- Select your model file (Please check the supported file formats)
- All model data will be stored inside the *.fmx file of your form
The IDE will show up a loading window while it's setting up the model.
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 data by the IDE and model data with textures.
===== Loading a model from at runtime =====
Besides the user-friendly loading at runtime, we of course support the model loading from file or stream.
You can also take advantage of the designtime mechanisms at runtime.
==== Loading a new model from file ====
Creating a model instance at runtime is very easy and often very helpful for creating dynamically loaded scenes.
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.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|Animations]] section.
You also can ignore the AssetPckg parameter currently. We will explain assets management in the [[assetsmanager|AssetsManager]] section.
==== 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.
uses
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.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 format unit:
* Gorilla.G3D.Loader
* Gorilla.DAE.Loader
* Gorilla.OBJ.Loader
* Gorilla.STL.Loader
* Gorilla.FBX.Loader (bugfixes and animations since v0.8.3.1966+)
* Gorilla.GLTF.Loader
* Gorilla.Babylon.Loader
* Gorilla.Sketchfab.Loader (uses glTF format)
* Gorilla.X3D.Loader
* Gorilla.X3DZ.Loader
* Gorilla.X3DVZ.Loader
* Gorilla.PLY.Loader (v0.8.3.1966+)
* Gorilla.SKP.Loader (v0.8.3.1966+)
Only then the format loader is able to load the specific file.
==== Loading a model from package ====
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.
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 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.
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;
===== Instancing / Model duplication =====
==== 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).
You can simply setup instanced rendering in your TGorillaModel or TGorillaMesh object.
{{youtube>WoJXVVjRHO0?large}}
/// we create 4 instances in a row
GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(-10, 0, 0)));
GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(-5, 0, 0)));
GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(5, 0, 0)));
GorillaModel1.AddInstance(TMatrix3D.CreateTranslation(Point3D(10, 0, 0)));
/// 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;
==== Instancing by template (TModelDef) ====
Since 0.8.3.1966+ we've refactored the way to instanciate models. The previous method was incomplete in handling animated models.
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.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;
===== Plugins =====
==== Sketchfab Plugin ====
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.
https://sketchfab.com/
**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 := ;
LOpts.FileInfo.ClientSecret := ;
LOpts.FileInfo.Username := ;
LOpts.FileInfo.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.
===== 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 ====
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;
Next step: [[animations|Animations]]