2
// This unit is part of the GLScene Engine https://github.com/glscene
5
B3D VectorFile class to load Blitz 3D model files
8
10/11/12 - PW - Added CPP compatibility: changed vector arrays to records
9
22/01/10 - Yar - Added GLVectorTypes to uses
10
22/01/10 - Yar - Added GLTextureFormat to uses
11
22/12/05 - Mathx - Added to the GLScene Project.
21
GLVectorFileObjects, GLApplicationFileIO, GLTexture, GLTextureFormat,
22
GLMaterial, GLVectorTypes, GLVectorGeometry, GLVectorLists,
27
TGLB3DVectorFile = class(TGLVectorFile)
29
class function Capabilities: TGLDataFileCapabilities; override;
30
procedure LoadFromStream(AStream: TStream); override;
35
// ------------------------------ TGLB3DVectorFile ------------------------------
38
class function TGLB3DVectorFile.Capabilities: TGLDataFileCapabilities;
45
procedure TGLB3DVectorFile.LoadFromStream(AStream: TStream);
52
FaceGroup: TFGVertexIndexList;
53
// lightmapBmp : TGLBitmap;
57
B3DLightTex: TB3DTexture;
59
Triangles: PTRISChunk;
62
MatLib: TGLMaterialLibrary;
63
LightLib: TGLMaterialLibrary;
67
function GetOrAllocateMaterial(MaterialNum: Integer; AMat: TB3DMaterial;
68
ATex: TB3DTexture; ALightmap: TB3DTexture): string;
70
LibMat: TGLLibMaterial;
74
if GetOwner is TGLBaseMesh then
76
MatLib := TGLBaseMesh(GetOwner).MaterialLibrary;
77
LightLib := TGLBaseMesh(GetOwner).LightmapLibrary;
78
// got a linked material library?
79
if Assigned(MatLib) then
81
Result := AMat.GetMaterialName;
83
LibMat := MatLib.Materials.GetLibMaterialByName(Result);
84
if not Assigned(LibMat) then
86
if Assigned(ATex) then
87
TexName := ATex.GetTextureName
91
if not FileExists(TexName) then
92
TexName := ExtractFileName(TexName);
94
LibMat := MatLib.AddTextureMaterial(Result + IntToStr(MaterialNum),
98
LibMat := MatLib.Materials.Add;
99
LibMat.Name := Result + IntToStr(MaterialNum);
102
Libmat.Material.FrontProperties.Diffuse.Red := AMat.MaterialData.Red;
103
Libmat.Material.FrontProperties.Diffuse.Green :=
104
AMat.MaterialData.Green;
105
Libmat.Material.FrontProperties.Diffuse.Blue :=
106
AMat.MaterialData.Blue;
107
Libmat.Material.FrontProperties.Diffuse.Alpha :=
108
AMat.MaterialData.Alpha;
109
Libmat.Material.FrontProperties.Shininess :=
110
Round(AMat.MaterialData.Shininess * 100.0);
111
Libmat.Material.MaterialOptions := [MoNoLighting];
113
if AMat.MaterialData.Alpha <> 1 then
115
Libmat.Material.FaceCulling := FcNoCull;
116
Libmat.Material.BlendingMode := BmTransparency;
119
if Assigned(ATex) then
122
LibMat.TextureOffset.AsAffineVector :=
123
AffineVectorMake(ATex.TextureData.X_pos,
124
ATex.TextureData.Y_pos, 0);
126
LibMat.TextureScale.AsAffineVector :=
127
AffineVectorMake(ATex.TextureData.X_scale,
128
ATex.TextureData.Y_scale, 1);
130
if ATex.TextureData.Flags = 2 then
132
Libmat.Material.FaceCulling := FcNoCull;
133
Libmat.Material.BlendingMode := BmTransparency;
136
if AMat.MaterialData.Alpha <> 1 then
138
Libmat.Material.Texture.ImageAlpha := TiaAlphaFromIntensity;
139
Libmat.Material.Texture.TextureFormat := TfRGBA;
140
Libmat.Material.Texture.TextureMode := TmModulate;
145
// add lightmap material
146
if (Assigned(LightLib)) and (Assigned(ALightmap)) then
148
LightName := ALightmap.GetTextureName;
150
LibMat := LightLib.Materials.GetLibMaterialByName(LightName
151
{ + IntToStr(MaterialNum) } );
152
if not Assigned(LibMat) then
154
if not FileExists(LightName) then
155
LightName := ExtractFileName(LightName);
157
LibMat := LightLib.AddTextureMaterial(LightName
158
{ + IntToStr(MaterialNum) } , LightName, False);
159
LibMat.Material.Texture.TextureMode := TmReplace;
160
if Assigned(ALightMap) then
163
LibMat.TextureOffset.AsAffineVector :=
164
AffineVectorMake(ALightMap.TextureData.X_pos,
165
ALightMap.TextureData.Y_pos, 0);
167
LibMat.TextureScale.AsAffineVector :=
168
AffineVectorMake(ALightMap.TextureData.X_scale,
169
ALightMap.TextureData.Y_scale, 1);
172
// modify the material lightmap index
173
AMat.MaterialData.Texture_id[1] := LibMat.Index;
184
B3d := TFileB3D.Create;
186
// first, load the b3d model sturctures from stream
187
B3d.LoadFromStream(AStream);
188
// then add all the materials and lightmaps from b3d structures
189
for I := 0 to B3d.Materials.Count - 1 do
191
B3DMat := TB3DMaterial(B3d.Materials.Objects[I]);
194
// check if there is one texture layer
195
if B3DMat.MaterialData.N_texs > 0 then
197
if B3DMat.MaterialData.Texture_id[0] >= 0 then
198
B3DTex := TB3DTexture(B3d.Textures.Objects
199
[B3DMat.MaterialData.Texture_id[0]]);
200
// check if there are two texture layer
201
if B3DMat.MaterialData.N_texs > 1 then
202
// why lightmap in some case on channel 2?
203
if B3DMat.MaterialData.Texture_id[1] >= 0 then
205
TB3DTexture(B3d.Textures.Objects
206
[B3DMat.MaterialData.Texture_id[1]])
208
{ //check if there are three texture layer }
209
if B3DMat.MaterialData.N_texs > 2 then
210
if B3DMat.MaterialData.Texture_id[2] >= 0 then
212
TB3DTexture(B3d.Textures.Objects
213
[B3DMat.MaterialData.Texture_id[2]]);
215
GetOrAllocateMaterial(I, B3DMat, B3DTex, B3DLightTex);
218
if GetOwner is TGLBaseMesh then
219
(GetOwner as TGLBaseMesh).NormalsOrientation := MnoDefault;
221
Node := B3d.Nodes.NodeData;
224
if Node^.Meshes <> nil then
226
Mo := TGLMeshObject.CreateOwned(Owner.MeshObjects);
228
SetString(S, Node^.Name, Strlen(Node^.Name));
229
// if Pos('16', s)>1 then
232
Mo.Mode := MomFaceGroups;
233
// add all the vertices, normals, colors and texture-coords(including the lightmap texture)
234
Vertex := Node^.Meshes^.Vertices.Vertices;
235
while Assigned(Vertex) do
237
// W3D modif inversed z
238
Mo.Vertices.Add(AffineVectorMake(Vertex^.Y, Vertex^.X, Vertex^.Z));
239
if (Node^.Meshes^.Vertices.Flags and 1) > 0 then
240
Mo.Normals.Add(VectorNormalize(AffineVectorMake(Vertex^.Ny,
241
Vertex^.Nx, Vertex^.Nz)));
243
if (Node^.Meshes^.Vertices.Flags and 2) > 0 then
245
Mo.Colors.Add(VectorMake(Vertex^.Red, Vertex^.Green, Vertex^.Blue,
249
case Node^.Meshes^.Vertices.Tex_coord_sets of
252
case Node^.Meshes^.Vertices.Tex_coord_set_size of
254
Mo.TexCoords.Add(Vertex^.Tex_coords[0],
255
-Vertex^.Tex_coords[1], 0);
257
Mo.TexCoords.Add(Vertex^.Tex_coords[0],
258
-Vertex^.Tex_coords[1], Vertex^.Tex_coords[2]);
261
2: // lightmap tex_coord included
263
case Node^.Meshes^.Vertices.Tex_coord_set_size of
265
Mo.TexCoords.Add(Vertex^.Tex_coords[0],
266
-Vertex^.Tex_coords[1], 0);
268
Mo.TexCoords.Add(Vertex^.Tex_coords[0],
269
-Vertex^.Tex_coords[1], Vertex^.Tex_coords[2]);
271
Mo.LightMapTexCoords.Add
273
[Node^.Meshes^.Vertices.Tex_coord_set_size],
275
[Node^.Meshes^.Vertices.Tex_coord_set_size + 1]);
278
Vertex := Vertex^.Next;
281
Triangles := Node^.Meshes^.Triangles;
282
while Assigned(Triangles) do
284
FaceGroup := TFGVertexIndexList.CreateOwned(Mo.FaceGroups);
285
if Triangles^.Brush_id >= 0 then
287
FaceGroup.MaterialName := B3d.Materials[Triangles^.Brush_id] +
288
InttoStr(Triangles^.Brush_id);
289
FaceGroup.LightMapIndex :=
290
TB3DMaterial(B3d.Materials.Objects[Triangles^.Brush_id])
291
.MaterialData.Texture_id[1];
295
FaceGroup.MaterialName := '';
296
FaceGroup.LightMapIndex := -1;
298
for J := 0 to Length(Triangles^.Vertex_id) - 1 do
299
FaceGroup.VertexIndices.Add(Triangles^.Vertex_id[J]);
300
while FaceGroup.VertexIndices.Count mod 3 <> 0 do
301
FaceGroup.VertexIndices.Delete(FaceGroup.VertexIndices.Count - 1);
302
Triangles := Triangles.Next;
307
RotQuat := QuaternionMake([Node^.Rotation.V[2], Node^.Rotation.V[1],
308
Node^.Rotation.V[3]], Node^.Rotation.V[0]);
309
RotMat := QuaternionToMatrix(RotQuat);
310
Mo.Vertices.TransformAsVectors(RotMat);
312
{ mo.SetPosition( Node^.Position[1], Node^.Position[0], Node^.Position[2]);
313
mo.SetScale( Node^.Scale[1], Node^.Scale[0], Node^.Scale[2]);
315
if Pos('ENT_', UpperCase(Mo.Name)) = 0 then
316
V := AffineVectorMake(Node^.Position.V[1],
317
Node^.Position.V[0], Node^.Position.V[2])
320
V := AffineVectorMake(0.0, 0.0, 0.0);
323
V1 := AffineVectorMake(Node^.Scale.V[1], Node^.Scale.V[0], Node^.Scale.V[2]);
324
Matrix := CreateScaleAndTranslationMatrix(VectorMake(V1), VectorMake(V));
325
Mo.Vertices.TransformAsPoints(Matrix);
336
// ------------------------------------------------------------------
337
// ------------------------------------------------------------------
338
// ------------------------------------------------------------------
340
RegisterVectorFileFormat('b3d', 'Blitz 3D model files', TGLB3DVectorFile);