2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Vector file object loading of Ghoul2 model and animation
9
24/03/07 - DaStr - Added explicit pointer dereferencing
10
(thanks Burkhard Carstens) (Bugtracker ID = 1678644)
11
22/10/03 - SG - Animation fixes, removed skeletal reconstruction
12
25/03/03 - SG - Creation.
20
Classes, SysUtils, GLVectorFileObjects, GLApplicationFileIO, GLMaterial,
21
GLVectorGeometry, FileGL2, GLVectorTypes, GLVectorLists;
25
TGLGLMVectorFile = class (TGLVectorFile)
27
class function Capabilities : TGLDataFileCapabilities; override;
28
procedure LoadFromStream(aStream : TStream); override;
31
TGLGLAVectorFile = class (TGLVectorFile)
33
class function Capabilities : TGLDataFileCapabilities; override;
34
procedure LoadFromStream(aStream : TStream); override;
38
vGhoul2LevelOfDetail : Integer = 0; // Highest detail level by default
39
vGhoul2MaxBonesPerVertex : Integer = 4; // Ghoul2 supports up to 4 bones
40
// per vertex. Use this global
41
// variable to set a different limit.
43
// ------------------------------------------------------------------
44
// ------------------------------------------------------------------
45
// ------------------------------------------------------------------
47
// ------------------------------------------------------------------
48
// ------------------------------------------------------------------
49
// ------------------------------------------------------------------
52
// ------------------ TGLGLMVectorFile ------------------
57
class function TGLGLMVectorFile.Capabilities : TGLDataFileCapabilities;
64
procedure TGLGLMVectorFile.LoadFromStream(aStream : TStream);
67
i,j,k,s,c,d : integer;
68
mesh : TGLSkeletonMeshObject;
69
fg : TFGVertexIndexList;
78
NumSurfVert : Integer;
80
procedure AllocateMaterial(meshname,shader:string);
82
LibMat : TGLLibMaterial;
84
if Assigned(Owner.MaterialLibrary) then with Owner.MaterialLibrary do begin
85
if Assigned(Materials.GetLibMaterialByName(meshname)) then exit;
86
LibMat:=Materials.Add;
87
LibMat.name:=meshname;
88
LibMat.Material.Texture.Disabled:=False;
93
GLMFile:=TFileGLM.Create;
94
GLMFile.LoadFromStream(aStream);
96
// Need a way to import all levels of detail, but this global
97
// variable will do for now.
98
d:=vGhoul2LevelOfDetail;
99
if d>=Length(GLMFile.LODs) then exit;
100
for s:=0 to Length(GLMFile.SurfaceHeirachy)-1 do begin
101
mesh:=TGLSkeletonMeshObject.CreateOwned(Owner.MeshObjects);
102
mesh.Mode:=momFaceGroups;
103
mesh.Name:=trim(GLMFile.SurfaceHeirachy[s].name);
104
shader:=trim(GLMFile.SurfaceHeirachy[s].shader);
105
AllocateMaterial(mesh.Name,shader);
107
// Set size of VerticesBonesWeights
109
for c:=0 to GLMFile.SurfaceHeirachy[s].numChildren-1 do begin
110
i:=GLMFile.SurfaceHeirachy[s].childIndices[c]-1;
111
NumSurfVert:=NumSurfVert+GLMFile.LODs[d].Surfaces[i].SurfaceHeader.numVerts;
113
mesh.BonesPerVertex:=vGhoul2MaxBonesPerVertex;
114
mesh.VerticeBoneWeightCount:=NumSurfVert;
115
for c:=0 to GLMFile.SurfaceHeirachy[s].numChildren-1 do begin
116
i:=GLMFile.SurfaceHeirachy[s].childIndices[c]-1;
117
with GLMFile.LODs[d].Surfaces[i] do begin
118
VertOfs:=mesh.Vertices.Count;
119
for j:=0 to Length(Vertices)-1 do begin
120
// Add vertices and normals
121
mesh.Vertices.Add(Vertices[j].vertex);
122
mesh.Normals.Add(Vertices[j].normal);
124
// Fix and then add the Texture coords
126
vec2.V[1]:=1-vec2.V[1]; // reverse the v coordinate
127
mesh.TexCoords.Add(vec2);
129
// Add weighted bones
130
numweights:=G2_GetVertWeights(Vertices[j]);
132
for k:=0 to mesh.BonesPerVertex-1 do
133
if k<numweights then begin
134
boneref:=G2_GetVertBoneIndex(Vertices[j],k);
135
boneid:=BoneReferences[boneref];
136
boneweight:=G2_GetVertBoneWeight(Vertices[j],k,weighttot,numweights);
137
mesh.VerticesBonesWeights^[mesh.Vertices.Count-1]^[k].BoneID:=boneid;
138
mesh.VerticesBonesWeights^[mesh.Vertices.Count-1]^[k].Weight:=boneweight;
140
mesh.VerticesBonesWeights^[mesh.Vertices.Count-1]^[k].BoneID:=0;
141
mesh.VerticesBonesWeights^[mesh.Vertices.Count-1]^[k].Weight:=0;
144
fg:=TFGVertexIndexList.CreateOwned(mesh.FaceGroups);
145
fg.Mode:=fgmmTriangles;
146
fg.MaterialName:=mesh.Name;
147
for j:=0 to Length(Triangles)-1 do begin
148
// The faces need to be wound in the opposite direction so...
149
fg.VertexIndices.Add(Triangles[j].indices[0]+VertOfs);
150
fg.VertexIndices.Add(Triangles[j].indices[2]+VertOfs);
151
fg.VertexIndices.Add(Triangles[j].indices[1]+VertOfs);
164
// ------------------ TGLGLAVectorFile ------------------
169
class function TGLGLAVectorFile.Capabilities : TGLDataFileCapabilities;
176
procedure TGLGLAVectorFile.LoadFromStream(aStream : TStream);
180
frame : TGLSkeletonFrame;
181
CompBone : TGLACompQuatBone;
184
basepose : TGLSkeletonFrame;
185
bonelist : TIntegerList;
186
bone : TGLSkeletonBone;
189
GLAFile:=TFileGLA.Create;
190
GLAFile.LoadFromStream(aStream);
192
if not (Owner is TGLActor) then exit;
194
TGLActor(Owner).Reference:=aarSkeleton;
196
bonelist:=TIntegerList.Create;
197
for i:=0 to GLAFile.AnimHeader.numBones-1 do
199
while bonelist.count>0 do begin
200
if GLAFile.Skeleton[bonelist[0]].parent = -1 then
201
bone:=TGLSkeletonBone.CreateOwned(Owner.Skeleton.RootBones)
203
bone:=Owner.Skeleton.RootBones.BoneByID(GLAFile.Skeleton[bonelist[0]].parent);
204
if Assigned(bone) then
205
bone:=TGLSkeletonBone.CreateOwned(bone)
207
if Assigned(bone) then begin
208
bone.Name:=GLAFile.Skeleton[bonelist[0]].Name;
209
bone.BoneID:=bonelist[0];
211
bonelist.Add(bonelist[0]);
216
// Build the base pose
217
basepose:=TGLSkeletonFrame.CreateOwned(TGLActor(Owner).Skeleton.Frames);
218
basepose.Name:='basepose';
219
basepose.TransformMode:=sftQuaternion;
220
basepose.Position.AddNulls(GLAFile.AnimHeader.numBones);
221
basepose.Quaternion.AddNulls(GLAFile.AnimHeader.numBones);
223
// Load animation data
224
for i:=0 to GLAFile.AnimHeader.numFrames-1 do begin
226
frame:=TGLSkeletonFrame.CreateOwned(TGLActor(Owner).Skeleton.Frames);
227
frame.Name:='Frame'+IntToStr(i);
228
frame.TransformMode:=sftQuaternion;
230
for j:=0 to GLAFile.AnimHeader.numBones-1 do begin
231
// Uncompress bone and add to the frame
232
CompBone:=GLAFile.GetCompressedMatrix(i,j);
233
quat:=QuaternionMake([CompBone[1]-32726,CompBone[2]-32726,CompBone[3]-32726],CompBone[0]-32726);
234
pos:=AffineVectorMake(CompBone[4]/64-512,CompBone[5]/64-512,CompBone[6]/64-512);
235
frame.Quaternion.Add(quat);
236
frame.Position.Add(pos);
240
Owner.Skeleton.RootBones.PrepareGlobalMatrices;
242
for i:=0 to Owner.MeshObjects.Count-1 do
243
TGLSkeletonMeshObject(Owner.MeshObjects[i]).PrepareBoneMatrixInvertedMeshes;
251
// ------------------------------------------------------------------
252
// ------------------------------------------------------------------
253
// ------------------------------------------------------------------
255
// ------------------------------------------------------------------
256
// ------------------------------------------------------------------
257
// ------------------------------------------------------------------
259
RegisterVectorFileFormat('glm', 'Ghoul2 (GLM) model files', TGLGLMVectorFile);
260
RegisterVectorFileFormat('glx', 'Ghoul2 (GLX) model files', TGLGLMVectorFile);
261
RegisterVectorFileFormat('gla', 'Ghoul2 (GLA) animation files', TGLGLAVectorFile);