aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshHalfLife.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 18:54:10 +1000
committerDavid Walter Seikel2013-01-13 18:54:10 +1000
commit959831f4ef5a3e797f576c3de08cd65032c997ad (patch)
treee7351908be5995f0b325b2ebeaa02d5a34b82583 /libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshHalfLife.cpp
parentAdd info about changes to Irrlicht. (diff)
downloadSledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.zip
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.gz
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.bz2
SledjHamr-959831f4ef5a3e797f576c3de08cd65032c997ad.tar.xz
Remove damned ancient DOS line endings from Irrlicht. Hopefully I did not go overboard.
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshHalfLife.cpp3390
1 files changed, 1695 insertions, 1695 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshHalfLife.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshHalfLife.cpp
index 6531e1a..ea81c59 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshHalfLife.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CAnimatedMeshHalfLife.cpp
@@ -1,1695 +1,1695 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt / Fabio Concas / Thomas Alten 1// Copyright (C) 2002-2012 Nikolaus Gebhardt / Fabio Concas / Thomas Alten
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5#include "IrrCompileConfig.h" 5#include "IrrCompileConfig.h"
6#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ 6#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_
7 7
8#include "CAnimatedMeshHalfLife.h" 8#include "CAnimatedMeshHalfLife.h"
9#include "os.h" 9#include "os.h"
10#include "CColorConverter.h" 10#include "CColorConverter.h"
11#include "CImage.h" 11#include "CImage.h"
12#include "coreutil.h" 12#include "coreutil.h"
13#include "SMeshBuffer.h" 13#include "SMeshBuffer.h"
14#include "IVideoDriver.h" 14#include "IVideoDriver.h"
15#include "IFileSystem.h" 15#include "IFileSystem.h"
16 16
17namespace irr 17namespace irr
18{ 18{
19namespace scene 19namespace scene
20{ 20{
21 21
22 using namespace video; 22 using namespace video;
23 23
24 void AngleQuaternion(const core::vector3df& angles, vec4_hl quaternion) 24 void AngleQuaternion(const core::vector3df& angles, vec4_hl quaternion)
25 { 25 {
26 f32 angle; 26 f32 angle;
27 f32 sr, sp, sy, cr, cp, cy; 27 f32 sr, sp, sy, cr, cp, cy;
28 28
29 // FIXME: rescale the inputs to 1/2 angle 29 // FIXME: rescale the inputs to 1/2 angle
30 angle = angles.Z * 0.5f; 30 angle = angles.Z * 0.5f;
31 sy = sin(angle); 31 sy = sin(angle);
32 cy = cos(angle); 32 cy = cos(angle);
33 angle = angles.Y * 0.5f; 33 angle = angles.Y * 0.5f;
34 sp = sin(angle); 34 sp = sin(angle);
35 cp = cos(angle); 35 cp = cos(angle);
36 angle = angles.X * 0.5f; 36 angle = angles.X * 0.5f;
37 sr = sin(angle); 37 sr = sin(angle);
38 cr = cos(angle); 38 cr = cos(angle);
39 39
40 quaternion[0] = sr*cp*cy-cr*sp*sy; // X 40 quaternion[0] = sr*cp*cy-cr*sp*sy; // X
41 quaternion[1] = cr*sp*cy+sr*cp*sy; // Y 41 quaternion[1] = cr*sp*cy+sr*cp*sy; // Y
42 quaternion[2] = cr*cp*sy-sr*sp*cy; // Z 42 quaternion[2] = cr*cp*sy-sr*sp*cy; // Z
43 quaternion[3] = cr*cp*cy+sr*sp*sy; // W 43 quaternion[3] = cr*cp*cy+sr*sp*sy; // W
44 } 44 }
45 45
46 void QuaternionMatrix( const vec4_hl quaternion, f32 (*matrix)[4] ) 46 void QuaternionMatrix( const vec4_hl quaternion, f32 (*matrix)[4] )
47 { 47 {
48 matrix[0][0] = 1.f - 2.f * quaternion[1] * quaternion[1] - 2.f * quaternion[2] * quaternion[2]; 48 matrix[0][0] = 1.f - 2.f * quaternion[1] * quaternion[1] - 2.f * quaternion[2] * quaternion[2];
49 matrix[1][0] = 2.f * quaternion[0] * quaternion[1] + 2.f * quaternion[3] * quaternion[2]; 49 matrix[1][0] = 2.f * quaternion[0] * quaternion[1] + 2.f * quaternion[3] * quaternion[2];
50 matrix[2][0] = 2.f * quaternion[0] * quaternion[2] - 2.f * quaternion[3] * quaternion[1]; 50 matrix[2][0] = 2.f * quaternion[0] * quaternion[2] - 2.f * quaternion[3] * quaternion[1];
51 51
52 matrix[0][1] = 2.f * quaternion[0] * quaternion[1] - 2.f * quaternion[3] * quaternion[2]; 52 matrix[0][1] = 2.f * quaternion[0] * quaternion[1] - 2.f * quaternion[3] * quaternion[2];
53 matrix[1][1] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[2] * quaternion[2]; 53 matrix[1][1] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[2] * quaternion[2];
54 matrix[2][1] = 2.f * quaternion[1] * quaternion[2] + 2.f * quaternion[3] * quaternion[0]; 54 matrix[2][1] = 2.f * quaternion[1] * quaternion[2] + 2.f * quaternion[3] * quaternion[0];
55 55
56 matrix[0][2] = 2.f * quaternion[0] * quaternion[2] + 2.f * quaternion[3] * quaternion[1]; 56 matrix[0][2] = 2.f * quaternion[0] * quaternion[2] + 2.f * quaternion[3] * quaternion[1];
57 matrix[1][2] = 2.f * quaternion[1] * quaternion[2] - 2.f * quaternion[3] * quaternion[0]; 57 matrix[1][2] = 2.f * quaternion[1] * quaternion[2] - 2.f * quaternion[3] * quaternion[0];
58 matrix[2][2] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[1] * quaternion[1]; 58 matrix[2][2] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[1] * quaternion[1];
59 } 59 }
60 60
61 void QuaternionSlerp( const vec4_hl p, vec4_hl q, f32 t, vec4_hl qt ) 61 void QuaternionSlerp( const vec4_hl p, vec4_hl q, f32 t, vec4_hl qt )
62 { 62 {
63 s32 i; 63 s32 i;
64 f32 omega, cosom, sinom, sclp, sclq; 64 f32 omega, cosom, sinom, sclp, sclq;
65 65
66 // decide if one of the quaternions is backwards 66 // decide if one of the quaternions is backwards
67 f32 a = 0; 67 f32 a = 0;
68 f32 b = 0; 68 f32 b = 0;
69 for (i = 0; i < 4; i++) { 69 for (i = 0; i < 4; i++) {
70 a += (p[i]-q[i])*(p[i]-q[i]); 70 a += (p[i]-q[i])*(p[i]-q[i]);
71 b += (p[i]+q[i])*(p[i]+q[i]); 71 b += (p[i]+q[i])*(p[i]+q[i]);
72 } 72 }
73 if (a > b) { 73 if (a > b) {
74 for (i = 0; i < 4; i++) { 74 for (i = 0; i < 4; i++) {
75 q[i] = -q[i]; 75 q[i] = -q[i];
76 } 76 }
77 } 77 }
78 78
79 cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; 79 cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3];
80 80
81 if ((1.f + cosom) > 0.00000001) { 81 if ((1.f + cosom) > 0.00000001) {
82 if ((1.f - cosom) > 0.00000001) { 82 if ((1.f - cosom) > 0.00000001) {
83 omega = acos( cosom ); 83 omega = acos( cosom );
84 sinom = sin( omega ); 84 sinom = sin( omega );
85 sclp = sin( (1.f - t)*omega) / sinom; 85 sclp = sin( (1.f - t)*omega) / sinom;
86 sclq = sin( t*omega ) / sinom; 86 sclq = sin( t*omega ) / sinom;
87 } 87 }
88 else { 88 else {
89 sclp = 1.f - t; 89 sclp = 1.f - t;
90 sclq = t; 90 sclq = t;
91 } 91 }
92 for (i = 0; i < 4; i++) { 92 for (i = 0; i < 4; i++) {
93 qt[i] = sclp * p[i] + sclq * q[i]; 93 qt[i] = sclp * p[i] + sclq * q[i];
94 } 94 }
95 } 95 }
96 else { 96 else {
97 qt[0] = -p[1]; 97 qt[0] = -p[1];
98 qt[1] = p[0]; 98 qt[1] = p[0];
99 qt[2] = -p[3]; 99 qt[2] = -p[3];
100 qt[3] = p[2]; 100 qt[3] = p[2];
101 sclp = sin( (1.f - t) * 0.5f * core::PI); 101 sclp = sin( (1.f - t) * 0.5f * core::PI);
102 sclq = sin( t * 0.5f * core::PI); 102 sclq = sin( t * 0.5f * core::PI);
103 for (i = 0; i < 3; i++) { 103 for (i = 0; i < 3; i++) {
104 qt[i] = sclp * p[i] + sclq * qt[i]; 104 qt[i] = sclp * p[i] + sclq * qt[i];
105 } 105 }
106 } 106 }
107 } 107 }
108 108
109 void R_ConcatTransforms (const f32 in1[3][4], const f32 in2[3][4], f32 out[3][4]) 109 void R_ConcatTransforms (const f32 in1[3][4], const f32 in2[3][4], f32 out[3][4])
110 { 110 {
111 out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0]; 111 out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
112 out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1]; 112 out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
113 out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2]; 113 out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
114 out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3]; 114 out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
115 out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0]; 115 out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
116 out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1]; 116 out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
117 out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2]; 117 out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
118 out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3]; 118 out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
119 out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0]; 119 out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
120 out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1]; 120 out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
121 out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2]; 121 out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
122 out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3]; 122 out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
123 } 123 }
124 124
125 #define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) 125 #define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
126 126
127 inline void VectorTransform(const vec3_hl in1, const f32 in2[3][4], core::vector3df& out) 127 inline void VectorTransform(const vec3_hl in1, const f32 in2[3][4], core::vector3df& out)
128 { 128 {
129 out.X = DotProduct(in1, in2[0]) + in2[0][3]; 129 out.X = DotProduct(in1, in2[0]) + in2[0][3];
130 out.Z = DotProduct(in1, in2[1]) + in2[1][3]; 130 out.Z = DotProduct(in1, in2[1]) + in2[1][3];
131 out.Y = DotProduct(in1, in2[2]) + in2[2][3]; 131 out.Y = DotProduct(in1, in2[2]) + in2[2][3];
132 } 132 }
133 133
134 static f32 BoneTransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix 134 static f32 BoneTransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix
135 135
136 void getBoneVector ( core::vector3df &out, u32 index ) 136 void getBoneVector ( core::vector3df &out, u32 index )
137 { 137 {
138 out.X = BoneTransform[index][0][3]; 138 out.X = BoneTransform[index][0][3];
139 out.Z = BoneTransform[index][1][3]; 139 out.Z = BoneTransform[index][1][3];
140 out.Y = BoneTransform[index][2][3]; 140 out.Y = BoneTransform[index][2][3];
141 } 141 }
142 142
143 void getBoneBox ( core::aabbox3df &box, u32 index, f32 size = 0.5f ) 143 void getBoneBox ( core::aabbox3df &box, u32 index, f32 size = 0.5f )
144 { 144 {
145 box.MinEdge.X = BoneTransform[index][0][3] - size; 145 box.MinEdge.X = BoneTransform[index][0][3] - size;
146 box.MinEdge.Z = BoneTransform[index][1][3] - size; 146 box.MinEdge.Z = BoneTransform[index][1][3] - size;
147 box.MinEdge.Y = BoneTransform[index][2][3] - size; 147 box.MinEdge.Y = BoneTransform[index][2][3] - size;
148 148
149 size *= 2.f; 149 size *= 2.f;
150 box.MaxEdge.X = box.MinEdge.X + size; 150 box.MaxEdge.X = box.MinEdge.X + size;
151 box.MaxEdge.Y = box.MinEdge.Y + size; 151 box.MaxEdge.Y = box.MinEdge.Y + size;
152 box.MaxEdge.Z = box.MinEdge.Z + size; 152 box.MaxEdge.Z = box.MinEdge.Z + size;
153 } 153 }
154 154
155 void getTransformedBoneVector ( core::vector3df &out, u32 index, const vec3_hl in) 155 void getTransformedBoneVector ( core::vector3df &out, u32 index, const vec3_hl in)
156 { 156 {
157 out.X = DotProduct(in, BoneTransform[index][0]) + BoneTransform[index][0][3]; 157 out.X = DotProduct(in, BoneTransform[index][0]) + BoneTransform[index][0][3];
158 out.Z = DotProduct(in, BoneTransform[index][1]) + BoneTransform[index][1][3]; 158 out.Z = DotProduct(in, BoneTransform[index][1]) + BoneTransform[index][1][3];
159 out.Y = DotProduct(in, BoneTransform[index][2]) + BoneTransform[index][2][3]; 159 out.Y = DotProduct(in, BoneTransform[index][2]) + BoneTransform[index][2][3];
160 160
161 } 161 }
162 162
163 163
164//! Constructor 164//! Constructor
165CHalflifeMDLMeshFileLoader::CHalflifeMDLMeshFileLoader( 165CHalflifeMDLMeshFileLoader::CHalflifeMDLMeshFileLoader(
166 scene::ISceneManager* smgr) : SceneManager(smgr) 166 scene::ISceneManager* smgr) : SceneManager(smgr)
167{ 167{
168#ifdef _DEBUG 168#ifdef _DEBUG
169 setDebugName("CHalflifeMDLMeshFileLoader"); 169 setDebugName("CHalflifeMDLMeshFileLoader");
170#endif 170#endif
171} 171}
172 172
173 173
174//! returns true if the file maybe is able to be loaded by this class 174//! returns true if the file maybe is able to be loaded by this class
175//! based on the file extension (e.g. ".bsp") 175//! based on the file extension (e.g. ".bsp")
176bool CHalflifeMDLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const 176bool CHalflifeMDLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
177{ 177{
178 return core::hasFileExtension(filename, "mdl"); 178 return core::hasFileExtension(filename, "mdl");
179} 179}
180 180
181 181
182//! creates/loads an animated mesh from the file. 182//! creates/loads an animated mesh from the file.
183//! \return Pointer to the created mesh. Returns 0 if loading failed. 183//! \return Pointer to the created mesh. Returns 0 if loading failed.
184//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). 184//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
185//! See IReferenceCounted::drop() for more information. 185//! See IReferenceCounted::drop() for more information.
186IAnimatedMesh* CHalflifeMDLMeshFileLoader::createMesh(io::IReadFile* file) 186IAnimatedMesh* CHalflifeMDLMeshFileLoader::createMesh(io::IReadFile* file)
187{ 187{
188 CAnimatedMeshHalfLife* msh = new CAnimatedMeshHalfLife(); 188 CAnimatedMeshHalfLife* msh = new CAnimatedMeshHalfLife();
189 if (msh) 189 if (msh)
190 { 190 {
191 if (msh->loadModelFile(file, SceneManager)) 191 if (msh->loadModelFile(file, SceneManager))
192 return msh; 192 return msh;
193 msh->drop(); 193 msh->drop();
194 } 194 }
195 195
196 return 0; 196 return 0;
197} 197}
198 198
199 199
200//! Constructor 200//! Constructor
201CAnimatedMeshHalfLife::CAnimatedMeshHalfLife() 201CAnimatedMeshHalfLife::CAnimatedMeshHalfLife()
202 : FrameCount(0), MeshIPol(0), SceneManager(0), Header(0), TextureHeader(0), 202 : FrameCount(0), MeshIPol(0), SceneManager(0), Header(0), TextureHeader(0),
203 OwnTexModel(false), SequenceIndex(0), CurrentFrame(0), FramesPerSecond(25.f), 203 OwnTexModel(false), SequenceIndex(0), CurrentFrame(0), FramesPerSecond(25.f),
204 SkinGroupSelection(0) 204 SkinGroupSelection(0)
205#ifdef HL_TEXTURE_ATLAS 205#ifdef HL_TEXTURE_ATLAS
206 , TextureMaster(0) 206 , TextureMaster(0)
207#endif 207#endif
208{ 208{
209#ifdef _DEBUG 209#ifdef _DEBUG
210 setDebugName("CAnimatedMeshHalfLife"); 210 setDebugName("CAnimatedMeshHalfLife");
211#endif 211#endif
212 initData(); 212 initData();
213} 213}
214 214
215/*! 215/*!
216 loads a complete model 216 loads a complete model
217*/ 217*/
218bool CAnimatedMeshHalfLife::loadModelFile(io::IReadFile* file, 218bool CAnimatedMeshHalfLife::loadModelFile(io::IReadFile* file,
219 ISceneManager* smgr) 219 ISceneManager* smgr)
220{ 220{
221 if (!file) 221 if (!file)
222 return false; 222 return false;
223 223
224 SceneManager = smgr; 224 SceneManager = smgr;
225 225
226 if ( loadModel(file, file->getFileName()) ) 226 if ( loadModel(file, file->getFileName()) )
227 { 227 {
228 if ( postLoadModel ( file->getFileName() ) ) 228 if ( postLoadModel ( file->getFileName() ) )
229 { 229 {
230 initModel (); 230 initModel ();
231 //dumpModelInfo ( 1 ); 231 //dumpModelInfo ( 1 );
232 return true; 232 return true;
233 } 233 }
234 } 234 }
235 return false; 235 return false;
236} 236}
237 237
238 238
239//! Destructor 239//! Destructor
240CAnimatedMeshHalfLife::~CAnimatedMeshHalfLife() 240CAnimatedMeshHalfLife::~CAnimatedMeshHalfLife()
241{ 241{
242 delete [] (u8*) Header; 242 delete [] (u8*) Header;
243 if (OwnTexModel) 243 if (OwnTexModel)
244 delete [] (u8*) TextureHeader; 244 delete [] (u8*) TextureHeader;
245 245
246 for (u32 i = 0; i < 32; ++i) 246 for (u32 i = 0; i < 32; ++i)
247 delete [] (u8*) AnimationHeader[i]; 247 delete [] (u8*) AnimationHeader[i];
248 248
249 if (MeshIPol) 249 if (MeshIPol)
250 MeshIPol->drop(); 250 MeshIPol->drop();
251} 251}
252 252
253 253
254//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. 254//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
255u32 CAnimatedMeshHalfLife::getFrameCount() const 255u32 CAnimatedMeshHalfLife::getFrameCount() const
256{ 256{
257 return FrameCount; 257 return FrameCount;
258} 258}
259 259
260 260
261//! set the hardware mapping hint, for driver 261//! set the hardware mapping hint, for driver
262void CAnimatedMeshHalfLife::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint,E_BUFFER_TYPE buffer) 262void CAnimatedMeshHalfLife::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint,E_BUFFER_TYPE buffer)
263{ 263{
264} 264}
265 265
266 266
267//! flags the meshbuffer as changed, reloads hardware buffers 267//! flags the meshbuffer as changed, reloads hardware buffers
268void CAnimatedMeshHalfLife::setDirty(E_BUFFER_TYPE buffer) 268void CAnimatedMeshHalfLife::setDirty(E_BUFFER_TYPE buffer)
269{ 269{
270} 270}
271 271
272 272
273static core::vector3df TransformedVerts[MAXSTUDIOVERTS]; // transformed vertices 273static core::vector3df TransformedVerts[MAXSTUDIOVERTS]; // transformed vertices
274//static core::vector3df TransformedNormals[MAXSTUDIOVERTS]; // light surface normals 274//static core::vector3df TransformedNormals[MAXSTUDIOVERTS]; // light surface normals
275 275
276 276
277/*! 277/*!
278*/ 278*/
279void CAnimatedMeshHalfLife::initModel() 279void CAnimatedMeshHalfLife::initModel()
280{ 280{
281 // init Sequences to Animation 281 // init Sequences to Animation
282 KeyFrameInterpolation ipol; 282 KeyFrameInterpolation ipol;
283 ipol.Name.reserve ( 64 ); 283 ipol.Name.reserve ( 64 );
284 u32 i; 284 u32 i;
285 285
286 AnimList.clear(); 286 AnimList.clear();
287 FrameCount = 0; 287 FrameCount = 0;
288 288
289 SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex); 289 SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex);
290 for ( i = 0; i < Header->numseq; i++) 290 for ( i = 0; i < Header->numseq; i++)
291 { 291 {
292 ipol.Name = seq[i].label; 292 ipol.Name = seq[i].label;
293 ipol.StartFrame = FrameCount; 293 ipol.StartFrame = FrameCount;
294 ipol.Frames = core::max_ ( 1, seq[i].numframes - 1 ); 294 ipol.Frames = core::max_ ( 1, seq[i].numframes - 1 );
295 ipol.EndFrame = ipol.StartFrame + ipol.Frames - 1; 295 ipol.EndFrame = ipol.StartFrame + ipol.Frames - 1;
296 ipol.FramesPerSecond = seq[i].fps; 296 ipol.FramesPerSecond = seq[i].fps;
297 ipol.AnimationType = seq[i].flags & STUDIO_LOOPING ? EAMT_LOOPING : EAMT_WAYPOINT; 297 ipol.AnimationType = seq[i].flags & STUDIO_LOOPING ? EAMT_LOOPING : EAMT_WAYPOINT;
298 AnimList.push_back ( ipol ); 298 AnimList.push_back ( ipol );
299 299
300 FrameCount += ipol.Frames; 300 FrameCount += ipol.Frames;
301 } 301 }
302 302
303 // initBoneControllers 303 // initBoneControllers
304/* 304/*
305 SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex); 305 SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex);
306 for ( i = 0; i < Header->numbonecontrollers; i++) 306 for ( i = 0; i < Header->numbonecontrollers; i++)
307 { 307 {
308 printf ( "BoneController%d index:%d%s range:%f - %f\n", 308 printf ( "BoneController%d index:%d%s range:%f - %f\n",
309 i, 309 i,
310 bonecontroller[i].index, bonecontroller[i].index == MOUTH_CONTROLLER ? " (Mouth)": "", 310 bonecontroller[i].index, bonecontroller[i].index == MOUTH_CONTROLLER ? " (Mouth)": "",
311 bonecontroller[i].start,bonecontroller[i].end 311 bonecontroller[i].start,bonecontroller[i].end
312 ); 312 );
313 } 313 }
314 314
315 // initSkins 315 // initSkins
316 for (i = 0; i < TextureHeader->numskinfamilies; i++) 316 for (i = 0; i < TextureHeader->numskinfamilies; i++)
317 { 317 {
318 printf ( "Skin%d\n", i + 1); 318 printf ( "Skin%d\n", i + 1);
319 } 319 }
320*/ 320*/
321 321
322 // initBodyparts 322 // initBodyparts
323 u32 meshBuffer = 0; 323 u32 meshBuffer = 0;
324 BodyList.clear(); 324 BodyList.clear();
325 SHalflifeBody *body = (SHalflifeBody *) ((u8*) Header + Header->bodypartindex); 325 SHalflifeBody *body = (SHalflifeBody *) ((u8*) Header + Header->bodypartindex);
326 for (i=0; i < Header->numbodyparts; ++i) 326 for (i=0; i < Header->numbodyparts; ++i)
327 { 327 {
328 BodyPart part; 328 BodyPart part;
329 part.name = body[i].name; 329 part.name = body[i].name;
330 part.defaultModel = core::max_ ( 0, (s32) body[i].base - 1 ); 330 part.defaultModel = core::max_ ( 0, (s32) body[i].base - 1 );
331 331
332 SHalflifeModel * model = (SHalflifeModel *)((u8*) Header + body[i].modelindex); 332 SHalflifeModel * model = (SHalflifeModel *)((u8*) Header + body[i].modelindex);
333 for ( u32 g = 0; g < body[i].nummodels; ++g) 333 for ( u32 g = 0; g < body[i].nummodels; ++g)
334 { 334 {
335 SubModel sub; 335 SubModel sub;
336 sub.name = model[g].name; 336 sub.name = model[g].name;
337 sub.startBuffer = meshBuffer; 337 sub.startBuffer = meshBuffer;
338 sub.endBuffer = sub.startBuffer + model[g].nummesh; 338 sub.endBuffer = sub.startBuffer + model[g].nummesh;
339 sub.state = g == part.defaultModel; 339 sub.state = g == part.defaultModel;
340 part.model.push_back ( sub ); 340 part.model.push_back ( sub );
341 meshBuffer += model[g].nummesh; 341 meshBuffer += model[g].nummesh;
342 } 342 }
343 BodyList.push_back ( part ); 343 BodyList.push_back ( part );
344 } 344 }
345 345
346 SequenceIndex = 0; 346 SequenceIndex = 0;
347 CurrentFrame = 0.f; 347 CurrentFrame = 0.f;
348 348
349 SetController(0, 0.f); 349 SetController(0, 0.f);
350 SetController(1, 0.f); 350 SetController(1, 0.f);
351 SetController(2, 0.f); 351 SetController(2, 0.f);
352 SetController(3, 0.f); 352 SetController(3, 0.f);
353 SetController(MOUTH_CONTROLLER, 0.f); 353 SetController(MOUTH_CONTROLLER, 0.f);
354 354
355 SetSkin (0); 355 SetSkin (0);
356 356
357 // init Meshbuffers 357 // init Meshbuffers
358 const SHalflifeTexture *tex = (SHalflifeTexture *) ((u8*) TextureHeader + TextureHeader->textureindex); 358 const SHalflifeTexture *tex = (SHalflifeTexture *) ((u8*) TextureHeader + TextureHeader->textureindex);
359 const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex); 359 const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex);
360 if ((SkinGroupSelection != 0) && (SkinGroupSelection < TextureHeader->numskinfamilies)) 360 if ((SkinGroupSelection != 0) && (SkinGroupSelection < TextureHeader->numskinfamilies))
361 skinref += (SkinGroupSelection * TextureHeader->numskinref); 361 skinref += (SkinGroupSelection * TextureHeader->numskinref);
362 362
363 core::vector2df tex_scale; 363 core::vector2df tex_scale;
364 core::vector2di tex_trans ( 0, 0 ); 364 core::vector2di tex_trans ( 0, 0 );
365 365
366#ifdef HL_TEXTURE_ATLAS 366#ifdef HL_TEXTURE_ATLAS
367 TextureAtlas.getScale(tex_scale); 367 TextureAtlas.getScale(tex_scale);
368#endif 368#endif
369 369
370 for (u32 bodypart=0 ; bodypart < Header->numbodyparts ; ++bodypart) 370 for (u32 bodypart=0 ; bodypart < Header->numbodyparts ; ++bodypart)
371 { 371 {
372 const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart; 372 const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart;
373 373
374 for (u32 modelnr = 0; modelnr < body->nummodels; ++modelnr) 374 for (u32 modelnr = 0; modelnr < body->nummodels; ++modelnr)
375 { 375 {
376 const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; 376 const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr;
377#if 0 377#if 0
378 const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex); 378 const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex);
379 const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex); 379 const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex);
380#endif 380#endif
381 for (i = 0; i < model->nummesh; ++i) 381 for (i = 0; i < model->nummesh; ++i)
382 { 382 {
383 const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i; 383 const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i;
384 const SHalflifeTexture *currentex = &tex[skinref[mesh->skinref]]; 384 const SHalflifeTexture *currentex = &tex[skinref[mesh->skinref]];
385 385
386#ifdef HL_TEXTURE_ATLAS 386#ifdef HL_TEXTURE_ATLAS
387 TextureAtlas.getTranslation ( currentex->name, tex_trans ); 387 TextureAtlas.getTranslation ( currentex->name, tex_trans );
388#else 388#else
389 tex_scale.X = 1.f/(f32)currentex->width; 389 tex_scale.X = 1.f/(f32)currentex->width;
390 tex_scale.Y = 1.f/(f32)currentex->height; 390 tex_scale.Y = 1.f/(f32)currentex->height;
391#endif 391#endif
392 392
393 SMeshBuffer * buffer = new SMeshBuffer(); 393 SMeshBuffer * buffer = new SMeshBuffer();
394 394
395 // count index vertex size indexcount = mesh->numtris * 3 395 // count index vertex size indexcount = mesh->numtris * 3
396 u32 indexCount = 0; 396 u32 indexCount = 0;
397 u32 vertexCount = 0; 397 u32 vertexCount = 0;
398 398
399 const s16 *tricmd = (s16*)((u8*)Header + mesh->triindex); 399 const s16 *tricmd = (s16*)((u8*)Header + mesh->triindex);
400 s32 c; 400 s32 c;
401 while ( (c = *(tricmd++)) ) 401 while ( (c = *(tricmd++)) )
402 { 402 {
403 if (c < 0) 403 if (c < 0)
404 c = -c; 404 c = -c;
405 405
406 indexCount += ( c - 2 ) * 3; 406 indexCount += ( c - 2 ) * 3;
407 vertexCount += c; 407 vertexCount += c;
408 tricmd += ( 4 * c ); 408 tricmd += ( 4 * c );
409 } 409 }
410 410
411 // indices 411 // indices
412 buffer->Indices.set_used ( indexCount ); 412 buffer->Indices.set_used ( indexCount );
413 buffer->Vertices.set_used ( vertexCount ); 413 buffer->Vertices.set_used ( vertexCount );
414 414
415 // fill in static indices and vertex 415 // fill in static indices and vertex
416 u16 *index = buffer->Indices.pointer(); 416 u16 *index = buffer->Indices.pointer();
417 video::S3DVertex * v = buffer->Vertices.pointer(); 417 video::S3DVertex * v = buffer->Vertices.pointer();
418 418
419 // blow up gl_triangle_fan/gl_triangle_strip to indexed triangle list 419 // blow up gl_triangle_fan/gl_triangle_strip to indexed triangle list
420 E_PRIMITIVE_TYPE type; 420 E_PRIMITIVE_TYPE type;
421 vertexCount = 0; 421 vertexCount = 0;
422 indexCount = 0; 422 indexCount = 0;
423 tricmd = (s16*)((u8*)Header + mesh->triindex); 423 tricmd = (s16*)((u8*)Header + mesh->triindex);
424 while ( (c = *(tricmd++)) ) 424 while ( (c = *(tricmd++)) )
425 { 425 {
426 if (c < 0) 426 if (c < 0)
427 { 427 {
428 // triangle fan 428 // triangle fan
429 c = -c; 429 c = -c;
430 type = EPT_TRIANGLE_FAN; 430 type = EPT_TRIANGLE_FAN;
431 } 431 }
432 else 432 else
433 { 433 {
434 type = EPT_TRIANGLE_STRIP; 434 type = EPT_TRIANGLE_STRIP;
435 } 435 }
436 436
437 for ( s32 g = 0; g < c; ++g, v += 1, tricmd += 4 ) 437 for ( s32 g = 0; g < c; ++g, v += 1, tricmd += 4 )
438 { 438 {
439 // fill vertex 439 // fill vertex
440 #if 0 440 #if 0
441 const f32 *av = studioverts[tricmd[0]]; 441 const f32 *av = studioverts[tricmd[0]];
442 v->Pos.X = av[0]; 442 v->Pos.X = av[0];
443 v->Pos.Z = av[1]; 443 v->Pos.Z = av[1];
444 v->Pos.Y = av[2]; 444 v->Pos.Y = av[2];
445 445
446 av = studionorms[tricmd[1]]; 446 av = studionorms[tricmd[1]];
447 v->Normal.X = av[0]; 447 v->Normal.X = av[0];
448 v->Normal.Z = av[1]; 448 v->Normal.Z = av[1];
449 v->Normal.Y = av[2]; 449 v->Normal.Y = av[2];
450 450
451 #endif 451 #endif
452 v->Normal.X = 0.f; 452 v->Normal.X = 0.f;
453 v->Normal.Z = 0.f; 453 v->Normal.Z = 0.f;
454 v->Normal.Y = 1.f; 454 v->Normal.Y = 1.f;
455 455
456 v->TCoords.X = (tex_trans.X + tricmd[2])*tex_scale.X; 456 v->TCoords.X = (tex_trans.X + tricmd[2])*tex_scale.X;
457 v->TCoords.Y = (tex_trans.Y + tricmd[3])*tex_scale.Y; 457 v->TCoords.Y = (tex_trans.Y + tricmd[3])*tex_scale.Y;
458 458
459 v->Color.color = 0xFFFFFFFF; 459 v->Color.color = 0xFFFFFFFF;
460 460
461 // fill index 461 // fill index
462 if ( g < c - 2 ) 462 if ( g < c - 2 )
463 { 463 {
464 if ( type == EPT_TRIANGLE_FAN ) 464 if ( type == EPT_TRIANGLE_FAN )
465 { 465 {
466 index[indexCount+0] = vertexCount; 466 index[indexCount+0] = vertexCount;
467 index[indexCount+1] = vertexCount+g+1; 467 index[indexCount+1] = vertexCount+g+1;
468 index[indexCount+2] = vertexCount+g+2; 468 index[indexCount+2] = vertexCount+g+2;
469 } 469 }
470 else 470 else
471 { 471 {
472 if ( g & 1 ) 472 if ( g & 1 )
473 { 473 {
474 index[indexCount+0] = vertexCount+g+1; 474 index[indexCount+0] = vertexCount+g+1;
475 index[indexCount+1] = vertexCount+g+0; 475 index[indexCount+1] = vertexCount+g+0;
476 index[indexCount+2] = vertexCount+g+2; 476 index[indexCount+2] = vertexCount+g+2;
477 } 477 }
478 else 478 else
479 { 479 {
480 index[indexCount+0] = vertexCount+g+0; 480 index[indexCount+0] = vertexCount+g+0;
481 index[indexCount+1] = vertexCount+g+1; 481 index[indexCount+1] = vertexCount+g+1;
482 index[indexCount+2] = vertexCount+g+2; 482 index[indexCount+2] = vertexCount+g+2;
483 } 483 }
484 } 484 }
485 485
486 indexCount += 3; 486 indexCount += 3;
487 } 487 }
488 } 488 }
489 489
490 vertexCount += c; 490 vertexCount += c;
491 } 491 }
492 492
493 // material 493 // material
494 video::SMaterial &m = buffer->getMaterial(); 494 video::SMaterial &m = buffer->getMaterial();
495 495
496 m.MaterialType = video::EMT_SOLID; 496 m.MaterialType = video::EMT_SOLID;
497 m.BackfaceCulling = true; 497 m.BackfaceCulling = true;
498 498
499 if ( currentex->flags & STUDIO_NF_CHROME ) 499 if ( currentex->flags & STUDIO_NF_CHROME )
500 { 500 {
501 // don't know what to do with chrome here 501 // don't know what to do with chrome here
502 } 502 }
503 503
504#ifdef HL_TEXTURE_ATLAS 504#ifdef HL_TEXTURE_ATLAS
505 io::path store = TextureBaseName + "atlas"; 505 io::path store = TextureBaseName + "atlas";
506#else 506#else
507 io::path fname; 507 io::path fname;
508 io::path ext; 508 io::path ext;
509 core::splitFilename ( currentex->name, 0, &fname, &ext ); 509 core::splitFilename ( currentex->name, 0, &fname, &ext );
510 io::path store = TextureBaseName + fname; 510 io::path store = TextureBaseName + fname;
511#endif 511#endif
512 m.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture ( store ); 512 m.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture ( store );
513 m.Lighting = false; 513 m.Lighting = false;
514 514
515 MeshIPol->addMeshBuffer(buffer); 515 MeshIPol->addMeshBuffer(buffer);
516 buffer->recalculateBoundingBox(); 516 buffer->recalculateBoundingBox();
517 buffer->drop(); 517 buffer->drop();
518 } // mesh 518 } // mesh
519 MeshIPol->recalculateBoundingBox(); 519 MeshIPol->recalculateBoundingBox();
520 } // model 520 } // model
521 } // body part 521 } // body part
522} 522}
523 523
524 524
525/*! 525/*!
526*/ 526*/
527void CAnimatedMeshHalfLife::buildVertices() 527void CAnimatedMeshHalfLife::buildVertices()
528{ 528{
529/* 529/*
530 const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex); 530 const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex);
531 if (SkinGroupSelection != 0 && SkinGroupSelection < TextureHeader->numskinfamilies) 531 if (SkinGroupSelection != 0 && SkinGroupSelection < TextureHeader->numskinfamilies)
532 skinref += (SkinGroupSelection * TextureHeader->numskinref); 532 skinref += (SkinGroupSelection * TextureHeader->numskinref);
533*/ 533*/
534 u32 i; 534 u32 i;
535 s32 c,g; 535 s32 c,g;
536 const s16 *tricmd; 536 const s16 *tricmd;
537 537
538 u32 meshBufferNr = 0; 538 u32 meshBufferNr = 0;
539 for ( u32 bodypart = 0 ; bodypart < Header->numbodyparts; ++bodypart) 539 for ( u32 bodypart = 0 ; bodypart < Header->numbodyparts; ++bodypart)
540 { 540 {
541 const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart; 541 const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart;
542 542
543 for ( u32 modelnr = 0; modelnr < body->nummodels; ++modelnr ) 543 for ( u32 modelnr = 0; modelnr < body->nummodels; ++modelnr )
544 { 544 {
545 const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; 545 const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr;
546 546
547 const u8 *vertbone = ((u8*)Header + model->vertinfoindex); 547 const u8 *vertbone = ((u8*)Header + model->vertinfoindex);
548 548
549 const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex); 549 const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex);
550 550
551 for ( i = 0; i < model->numverts; i++) 551 for ( i = 0; i < model->numverts; i++)
552 { 552 {
553 VectorTransform ( studioverts[i], BoneTransform[vertbone[i]], TransformedVerts[i] ); 553 VectorTransform ( studioverts[i], BoneTransform[vertbone[i]], TransformedVerts[i] );
554 } 554 }
555 /* 555 /*
556 const u8 *normbone = ((u8*)Header + model->norminfoindex); 556 const u8 *normbone = ((u8*)Header + model->norminfoindex);
557 const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex); 557 const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex);
558 for ( i = 0; i < model->numnorms; i++) 558 for ( i = 0; i < model->numnorms; i++)
559 { 559 {
560 VectorTransform ( studionorms[i], BoneTransform[normbone[i]], TransformedNormals[i] ); 560 VectorTransform ( studionorms[i], BoneTransform[normbone[i]], TransformedNormals[i] );
561 } 561 }
562 */ 562 */
563 for (i = 0; i < model->nummesh; i++) 563 for (i = 0; i < model->nummesh; i++)
564 { 564 {
565 const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i; 565 const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i;
566 566
567 IMeshBuffer * buffer = MeshIPol->getMeshBuffer ( meshBufferNr++ ); 567 IMeshBuffer * buffer = MeshIPol->getMeshBuffer ( meshBufferNr++ );
568 video::S3DVertex* v = (video::S3DVertex* ) buffer->getVertices(); 568 video::S3DVertex* v = (video::S3DVertex* ) buffer->getVertices();
569 569
570 tricmd = (s16*)((u8*)Header + mesh->triindex); 570 tricmd = (s16*)((u8*)Header + mesh->triindex);
571 while ( (c = *(tricmd++)) ) 571 while ( (c = *(tricmd++)) )
572 { 572 {
573 if (c < 0) 573 if (c < 0)
574 c = -c; 574 c = -c;
575 575
576 for ( g = 0; g < c; ++g, v += 1, tricmd += 4 ) 576 for ( g = 0; g < c; ++g, v += 1, tricmd += 4 )
577 { 577 {
578 // fill vertex 578 // fill vertex
579 const core::vector3df& av = TransformedVerts[tricmd[0]]; 579 const core::vector3df& av = TransformedVerts[tricmd[0]];
580 v->Pos = av; 580 v->Pos = av;
581 /* 581 /*
582 const core::vector3df& an = TransformedNormals[tricmd[1]]; 582 const core::vector3df& an = TransformedNormals[tricmd[1]];
583 v->Normal = an; 583 v->Normal = an;
584 //v->Normal.normalize(); 584 //v->Normal.normalize();
585 */ 585 */
586 } 586 }
587 } // tricmd 587 } // tricmd
588 } // nummesh 588 } // nummesh
589 } // model 589 } // model
590 } // bodypart 590 } // bodypart
591} 591}
592 592
593 593
594/*! 594/*!
595 render Bones 595 render Bones
596*/ 596*/
597void CAnimatedMeshHalfLife::renderModel(u32 param, IVideoDriver * driver, const core::matrix4 &absoluteTransformation) 597void CAnimatedMeshHalfLife::renderModel(u32 param, IVideoDriver * driver, const core::matrix4 &absoluteTransformation)
598{ 598{
599 SHalflifeBone *bone = (SHalflifeBone *) ((u8 *) Header + Header->boneindex); 599 SHalflifeBone *bone = (SHalflifeBone *) ((u8 *) Header + Header->boneindex);
600 600
601 video::SColor blue(0xFF000080); 601 video::SColor blue(0xFF000080);
602 video::SColor red(0xFF800000); 602 video::SColor red(0xFF800000);
603 video::SColor yellow(0xFF808000); 603 video::SColor yellow(0xFF808000);
604 video::SColor cyan(0xFF008080); 604 video::SColor cyan(0xFF008080);
605 605
606 core::aabbox3df box; 606 core::aabbox3df box;
607 607
608 u32 i; 608 u32 i;
609 for ( i = 0; i < Header->numbones; i++) 609 for ( i = 0; i < Header->numbones; i++)
610 { 610 {
611 if (bone[i].parent >= 0) 611 if (bone[i].parent >= 0)
612 { 612 {
613 getBoneVector ( box.MinEdge, bone[i].parent ); 613 getBoneVector ( box.MinEdge, bone[i].parent );
614 getBoneVector ( box.MaxEdge, i ); 614 getBoneVector ( box.MaxEdge, i );
615 driver->draw3DLine ( box.MinEdge, box.MaxEdge, blue ); 615 driver->draw3DLine ( box.MinEdge, box.MaxEdge, blue );
616 616
617 // draw parent bone node 617 // draw parent bone node
618 if (bone[bone[i].parent].parent >=0 ) 618 if (bone[bone[i].parent].parent >=0 )
619 { 619 {
620 getBoneBox ( box, bone[i].parent ); 620 getBoneBox ( box, bone[i].parent );
621 driver->draw3DBox ( box, blue ); 621 driver->draw3DBox ( box, blue );
622 } 622 }
623 getBoneBox ( box, i ); 623 getBoneBox ( box, i );
624 driver->draw3DBox ( box, blue ); 624 driver->draw3DBox ( box, blue );
625 } 625 }
626 else 626 else
627 { 627 {
628 // draw parent bone node 628 // draw parent bone node
629 getBoneBox ( box, i, 1.f ); 629 getBoneBox ( box, i, 1.f );
630 driver->draw3DBox ( box , red ); 630 driver->draw3DBox ( box , red );
631 } 631 }
632 } 632 }
633 633
634 // attachements 634 // attachements
635 SHalflifeAttachment *attach = (SHalflifeAttachment *) ((u8*) Header + Header->attachmentindex); 635 SHalflifeAttachment *attach = (SHalflifeAttachment *) ((u8*) Header + Header->attachmentindex);
636 core::vector3df v[8]; 636 core::vector3df v[8];
637 for ( i = 0; i < Header->numattachments; i++) 637 for ( i = 0; i < Header->numattachments; i++)
638 { 638 {
639 getTransformedBoneVector ( v[0],attach[i].bone,attach[i].org ); 639 getTransformedBoneVector ( v[0],attach[i].bone,attach[i].org );
640 getTransformedBoneVector ( v[1],attach[i].bone,attach[i].vectors[0] ); 640 getTransformedBoneVector ( v[1],attach[i].bone,attach[i].vectors[0] );
641 getTransformedBoneVector ( v[2],attach[i].bone,attach[i].vectors[1] ); 641 getTransformedBoneVector ( v[2],attach[i].bone,attach[i].vectors[1] );
642 getTransformedBoneVector ( v[3],attach[i].bone,attach[i].vectors[2] ); 642 getTransformedBoneVector ( v[3],attach[i].bone,attach[i].vectors[2] );
643 driver->draw3DLine ( v[0], v[1], cyan ); 643 driver->draw3DLine ( v[0], v[1], cyan );
644 driver->draw3DLine ( v[0], v[2], cyan ); 644 driver->draw3DLine ( v[0], v[2], cyan );
645 driver->draw3DLine ( v[0], v[3], cyan ); 645 driver->draw3DLine ( v[0], v[3], cyan );
646 } 646 }
647 647
648 // hit boxes 648 // hit boxes
649 SHalflifeBBox *hitbox = (SHalflifeBBox *) ((u8*) Header + Header->hitboxindex); 649 SHalflifeBBox *hitbox = (SHalflifeBBox *) ((u8*) Header + Header->hitboxindex);
650 f32 *bbmin,*bbmax; 650 f32 *bbmin,*bbmax;
651 vec3_hl v2[8]; 651 vec3_hl v2[8];
652 for (i = 0; i < Header->numhitboxes; i++) 652 for (i = 0; i < Header->numhitboxes; i++)
653 { 653 {
654 bbmin = hitbox[i].bbmin; 654 bbmin = hitbox[i].bbmin;
655 bbmax = hitbox[i].bbmax; 655 bbmax = hitbox[i].bbmax;
656 656
657 v2[0][0] = bbmin[0]; 657 v2[0][0] = bbmin[0];
658 v2[0][1] = bbmax[1]; 658 v2[0][1] = bbmax[1];
659 v2[0][2] = bbmin[2]; 659 v2[0][2] = bbmin[2];
660 660
661 v2[1][0] = bbmin[0]; 661 v2[1][0] = bbmin[0];
662 v2[1][1] = bbmin[1]; 662 v2[1][1] = bbmin[1];
663 v2[1][2] = bbmin[2]; 663 v2[1][2] = bbmin[2];
664 664
665 v2[2][0] = bbmax[0]; 665 v2[2][0] = bbmax[0];
666 v2[2][1] = bbmax[1]; 666 v2[2][1] = bbmax[1];
667 v2[2][2] = bbmin[2]; 667 v2[2][2] = bbmin[2];
668 668
669 v2[3][0] = bbmax[0]; 669 v2[3][0] = bbmax[0];
670 v2[3][1] = bbmin[1]; 670 v2[3][1] = bbmin[1];
671 v2[3][2] = bbmin[2]; 671 v2[3][2] = bbmin[2];
672 672
673 v2[4][0] = bbmax[0]; 673 v2[4][0] = bbmax[0];
674 v2[4][1] = bbmax[1]; 674 v2[4][1] = bbmax[1];
675 v2[4][2] = bbmax[2]; 675 v2[4][2] = bbmax[2];
676 676
677 v2[5][0] = bbmax[0]; 677 v2[5][0] = bbmax[0];
678 v2[5][1] = bbmin[1]; 678 v2[5][1] = bbmin[1];
679 v2[5][2] = bbmax[2]; 679 v2[5][2] = bbmax[2];
680 680
681 v2[6][0] = bbmin[0]; 681 v2[6][0] = bbmin[0];
682 v2[6][1] = bbmax[1]; 682 v2[6][1] = bbmax[1];
683 v2[6][2] = bbmax[2]; 683 v2[6][2] = bbmax[2];
684 684
685 v2[7][0] = bbmin[0]; 685 v2[7][0] = bbmin[0];
686 v2[7][1] = bbmin[1]; 686 v2[7][1] = bbmin[1];
687 v2[7][2] = bbmax[2]; 687 v2[7][2] = bbmax[2];
688 688
689 for ( u32 g = 0; g < 8; ++g ) 689 for ( u32 g = 0; g < 8; ++g )
690 getTransformedBoneVector ( v[g],hitbox[i].bone,v2[g] ); 690 getTransformedBoneVector ( v[g],hitbox[i].bone,v2[g] );
691 691
692 driver->draw3DLine(v[0], v[1], yellow); 692 driver->draw3DLine(v[0], v[1], yellow);
693 driver->draw3DLine(v[1], v[3], yellow); 693 driver->draw3DLine(v[1], v[3], yellow);
694 driver->draw3DLine(v[3], v[2], yellow); 694 driver->draw3DLine(v[3], v[2], yellow);
695 driver->draw3DLine(v[2], v[0], yellow); 695 driver->draw3DLine(v[2], v[0], yellow);
696 696
697 driver->draw3DLine(v[4], v[5], yellow); 697 driver->draw3DLine(v[4], v[5], yellow);
698 driver->draw3DLine(v[5], v[7], yellow); 698 driver->draw3DLine(v[5], v[7], yellow);
699 driver->draw3DLine(v[7], v[6], yellow); 699 driver->draw3DLine(v[7], v[6], yellow);
700 driver->draw3DLine(v[6], v[4], yellow); 700 driver->draw3DLine(v[6], v[4], yellow);
701 701
702 driver->draw3DLine(v[0], v[6], yellow); 702 driver->draw3DLine(v[0], v[6], yellow);
703 driver->draw3DLine(v[1], v[7], yellow); 703 driver->draw3DLine(v[1], v[7], yellow);
704 driver->draw3DLine(v[3], v[5], yellow); 704 driver->draw3DLine(v[3], v[5], yellow);
705 driver->draw3DLine(v[2], v[4], yellow); 705 driver->draw3DLine(v[2], v[4], yellow);
706 } 706 }
707} 707}
708 708
709 709
710//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. 710//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail.
711IMesh* CAnimatedMeshHalfLife::getMesh(s32 frameInt, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) 711IMesh* CAnimatedMeshHalfLife::getMesh(s32 frameInt, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
712{ 712{
713 f32 frame = frameInt + (detailLevel * 0.001f); 713 f32 frame = frameInt + (detailLevel * 0.001f);
714 u32 frameA = core::floor32 ( frame ); 714 u32 frameA = core::floor32 ( frame );
715// f32 blend = core::fract ( frame ); 715// f32 blend = core::fract ( frame );
716 716
717 SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex); 717 SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex);
718 718
719 // find SequenceIndex from summed list 719 // find SequenceIndex from summed list
720 u32 frameCount = 0; 720 u32 frameCount = 0;
721 for (u32 i = 0; i < Header->numseq; ++i) 721 for (u32 i = 0; i < Header->numseq; ++i)
722 { 722 {
723 u32 val = core::max_ ( 1, seq[i].numframes - 1 ); 723 u32 val = core::max_ ( 1, seq[i].numframes - 1 );
724 if ( frameCount + val > frameA ) 724 if ( frameCount + val > frameA )
725 { 725 {
726 SequenceIndex = i; 726 SequenceIndex = i;
727 CurrentFrame = frame - frameCount; 727 CurrentFrame = frame - frameCount;
728 break; 728 break;
729 } 729 }
730 frameCount += val; 730 frameCount += val;
731 } 731 }
732 732
733 seq += SequenceIndex; 733 seq += SequenceIndex;
734 734
735 //SetBodyPart ( 1, 1 ); 735 //SetBodyPart ( 1, 1 );
736 setUpBones (); 736 setUpBones ();
737 buildVertices(); 737 buildVertices();
738 738
739 MeshIPol->BoundingBox.MinEdge.X = seq->bbmin[0]; 739 MeshIPol->BoundingBox.MinEdge.X = seq->bbmin[0];
740 MeshIPol->BoundingBox.MinEdge.Z = seq->bbmin[1]; 740 MeshIPol->BoundingBox.MinEdge.Z = seq->bbmin[1];
741 MeshIPol->BoundingBox.MinEdge.Y = seq->bbmin[2]; 741 MeshIPol->BoundingBox.MinEdge.Y = seq->bbmin[2];
742 742
743 MeshIPol->BoundingBox.MaxEdge.X = seq->bbmax[0]; 743 MeshIPol->BoundingBox.MaxEdge.X = seq->bbmax[0];
744 MeshIPol->BoundingBox.MaxEdge.Z = seq->bbmax[1]; 744 MeshIPol->BoundingBox.MaxEdge.Z = seq->bbmax[1];
745 MeshIPol->BoundingBox.MaxEdge.Y = seq->bbmax[2]; 745 MeshIPol->BoundingBox.MaxEdge.Y = seq->bbmax[2];
746 746
747 return MeshIPol; 747 return MeshIPol;
748} 748}
749 749
750 750
751/*! 751/*!
752*/ 752*/
753void CAnimatedMeshHalfLife::initData () 753void CAnimatedMeshHalfLife::initData ()
754{ 754{
755 u32 i; 755 u32 i;
756 756
757 Header = 0; 757 Header = 0;
758 TextureHeader = 0; 758 TextureHeader = 0;
759 OwnTexModel = false; 759 OwnTexModel = false;
760 760
761 for ( i = 0; i < 32; ++i ) 761 for ( i = 0; i < 32; ++i )
762 AnimationHeader[i] = 0; 762 AnimationHeader[i] = 0;
763 763
764 SequenceIndex = 0; 764 SequenceIndex = 0;
765 CurrentFrame = 0.f; 765 CurrentFrame = 0.f;
766 766
767 for ( i = 0; i < 5; ++i ) 767 for ( i = 0; i < 5; ++i )
768 BoneController[i] = 0; 768 BoneController[i] = 0;
769 769
770 for ( i = 0; i < 2; ++i ) 770 for ( i = 0; i < 2; ++i )
771 Blending[i] = 0; 771 Blending[i] = 0;
772 772
773 SkinGroupSelection = 0; 773 SkinGroupSelection = 0;
774 774
775 AnimList.clear(); 775 AnimList.clear();
776 FrameCount = 0; 776 FrameCount = 0;
777 777
778 if (!MeshIPol) 778 if (!MeshIPol)
779 MeshIPol = new SMesh(); 779 MeshIPol = new SMesh();
780 MeshIPol->clear(); 780 MeshIPol->clear();
781 781
782#ifdef HL_TEXTURE_ATLAS 782#ifdef HL_TEXTURE_ATLAS
783 TextureAtlas.release(); 783 TextureAtlas.release();
784#endif 784#endif
785} 785}
786 786
787 787
788/*! 788/*!
789*/ 789*/
790void STextureAtlas::release() 790void STextureAtlas::release()
791{ 791{
792 for (u32 i = 0; i < atlas.size(); i++) 792 for (u32 i = 0; i < atlas.size(); i++)
793 { 793 {
794 if ( atlas[i].image ) 794 if ( atlas[i].image )
795 { 795 {
796 atlas[i].image->drop(); 796 atlas[i].image->drop();
797 atlas[i].image = 0; 797 atlas[i].image = 0;
798 } 798 }
799 } 799 }
800 Master = 0; 800 Master = 0;
801} 801}
802 802
803 803
804/*! 804/*!
805*/ 805*/
806void STextureAtlas::addSource ( const c8 * name, video::IImage * image ) 806void STextureAtlas::addSource ( const c8 * name, video::IImage * image )
807{ 807{
808 TextureAtlasEntry entry; 808 TextureAtlasEntry entry;
809 entry.name = name; 809 entry.name = name;
810 entry.image = image; 810 entry.image = image;
811 entry.width = image->getDimension().Width; 811 entry.width = image->getDimension().Width;
812 entry.height = image->getDimension().Height; 812 entry.height = image->getDimension().Height;
813 entry.pos.X = 0; 813 entry.pos.X = 0;
814 entry.pos.Y = 0; 814 entry.pos.Y = 0;
815 atlas.push_back ( entry ); 815 atlas.push_back ( entry );
816} 816}
817 817
818 818
819/*! 819/*!
820*/ 820*/
821void STextureAtlas::getScale(core::vector2df& scale) 821void STextureAtlas::getScale(core::vector2df& scale)
822{ 822{
823 for (s32 i = static_cast<s32>(atlas.size()) - 1; i >= 0; --i) 823 for (s32 i = static_cast<s32>(atlas.size()) - 1; i >= 0; --i)
824 { 824 {
825 if ( atlas[i].name == "_merged_" ) 825 if ( atlas[i].name == "_merged_" )
826 { 826 {
827 scale.X = 1.f / atlas[i].width; 827 scale.X = 1.f / atlas[i].width;
828 scale.Y = 1.f / atlas[i].height; 828 scale.Y = 1.f / atlas[i].height;
829 return; 829 return;
830 } 830 }
831 } 831 }
832 scale.X = 1.f; 832 scale.X = 1.f;
833 scale.Y = 1.f; 833 scale.Y = 1.f;
834} 834}
835 835
836 836
837/*! 837/*!
838*/ 838*/
839void STextureAtlas::getTranslation(const c8* name, core::vector2di& pos) 839void STextureAtlas::getTranslation(const c8* name, core::vector2di& pos)
840{ 840{
841 for ( u32 i = 0; i < atlas.size(); ++i) 841 for ( u32 i = 0; i < atlas.size(); ++i)
842 { 842 {
843 if ( atlas[i].name == name ) 843 if ( atlas[i].name == name )
844 { 844 {
845 pos = atlas[i].pos; 845 pos = atlas[i].pos;
846 return; 846 return;
847 } 847 }
848 } 848 }
849} 849}
850 850
851 851
852/*! 852/*!
853*/ 853*/
854void STextureAtlas::create(u32 border, E_TEXTURE_CLAMP texmode) 854void STextureAtlas::create(u32 border, E_TEXTURE_CLAMP texmode)
855{ 855{
856 u32 i = 0; 856 u32 i = 0;
857 u32 w = 0; 857 u32 w = 0;
858 u32 w2; 858 u32 w2;
859 u32 h2; 859 u32 h2;
860 u32 h; 860 u32 h;
861 u32 wsum; 861 u32 wsum;
862 u32 hsum = 0; 862 u32 hsum = 0;
863 ECOLOR_FORMAT format = ECF_R8G8B8; 863 ECOLOR_FORMAT format = ECF_R8G8B8;
864 864
865 const s32 frame = core::s32_max ( 0, (border - 1 ) / 2 ); 865 const s32 frame = core::s32_max ( 0, (border - 1 ) / 2 );
866 866
867 // sort for biggest coming first 867 // sort for biggest coming first
868 atlas.sort(); 868 atlas.sort();
869 869
870 // split size 870 // split size
871 wsum = frame; 871 wsum = frame;
872 for (i = 0; i < atlas.size(); i++) 872 for (i = 0; i < atlas.size(); i++)
873 { 873 {
874 // make space 874 // make space
875 w2 = atlas[i].width + border; 875 w2 = atlas[i].width + border;
876 876
877 // align 877 // align
878 w2 = (w2 + 1) & ~1; 878 w2 = (w2 + 1) & ~1;
879 wsum += w2; 879 wsum += w2;
880 } 880 }
881 u32 splitsize = 256; 881 u32 splitsize = 256;
882 if ( wsum > 512 ) 882 if ( wsum > 512 )
883 splitsize = 512; 883 splitsize = 512;
884 884
885 wsum = frame; 885 wsum = frame;
886 hsum = frame; 886 hsum = frame;
887 w = frame; 887 w = frame;
888 h = 0; 888 h = 0;
889 for (i = 0; i < atlas.size(); i++) 889 for (i = 0; i < atlas.size(); i++)
890 { 890 {
891 if ( atlas[i].image->getColorFormat() == ECF_A8R8G8B8 ) 891 if ( atlas[i].image->getColorFormat() == ECF_A8R8G8B8 )
892 { 892 {
893 format = ECF_A8R8G8B8; 893 format = ECF_A8R8G8B8;
894 } 894 }
895 895
896 // make space 896 // make space
897 w2 = atlas[i].width + border; 897 w2 = atlas[i].width + border;
898 h2 = atlas[i].height + border; 898 h2 = atlas[i].height + border;
899 899
900 // align 900 // align
901 w2 = (w2 + 1) & ~1; 901 w2 = (w2 + 1) & ~1;
902 h2 = (h2 + 1) & ~1; 902 h2 = (h2 + 1) & ~1;
903 903
904 h = core::s32_max ( h, h2 ); 904 h = core::s32_max ( h, h2 );
905 905
906 if ( w + w2 >= splitsize ) 906 if ( w + w2 >= splitsize )
907 { 907 {
908 hsum += h; 908 hsum += h;
909 wsum = core::s32_max ( wsum, w ); 909 wsum = core::s32_max ( wsum, w );
910 h = h2; 910 h = h2;
911 w = frame; 911 w = frame;
912 } 912 }
913 913
914 atlas[i].pos.X = w; 914 atlas[i].pos.X = w;
915 atlas[i].pos.Y = hsum; 915 atlas[i].pos.Y = hsum;
916 916
917 w += w2; 917 w += w2;
918 918
919 } 919 }
920 hsum += h; 920 hsum += h;
921 wsum = core::s32_max ( wsum, w ); 921 wsum = core::s32_max ( wsum, w );
922 922
923 // build image 923 // build image
924 core::dimension2d<u32> dim = core::dimension2d<u32>( wsum, hsum ).getOptimalSize(); 924 core::dimension2d<u32> dim = core::dimension2d<u32>( wsum, hsum ).getOptimalSize();
925 IImage* master = new CImage(format, dim); 925 IImage* master = new CImage(format, dim);
926 master->fill(0); 926 master->fill(0);
927 927
928 video::SColor col[2]; 928 video::SColor col[2];
929 929
930 static const u8 wrap[][4] = 930 static const u8 wrap[][4] =
931 { 931 {
932 {1, 0}, // ETC_REPEAT 932 {1, 0}, // ETC_REPEAT
933 {0, 1}, // ETC_CLAMP 933 {0, 1}, // ETC_CLAMP
934 {0, 1}, // ETC_CLAMP_TO_EDGE 934 {0, 1}, // ETC_CLAMP_TO_EDGE
935 {0, 1} // ETC_MIRROR 935 {0, 1} // ETC_MIRROR
936 }; 936 };
937 937
938 s32 a,b; 938 s32 a,b;
939 for (i = 0; i < atlas.size(); i++) 939 for (i = 0; i < atlas.size(); i++)
940 { 940 {
941 atlas[i].image->copyTo ( master, atlas[i].pos ); 941 atlas[i].image->copyTo ( master, atlas[i].pos );
942 942
943 // clamp/wrap ( copy edges, filtering needs it ) 943 // clamp/wrap ( copy edges, filtering needs it )
944 944
945 for ( b = 0; b < frame; ++b ) 945 for ( b = 0; b < frame; ++b )
946 { 946 {
947 for ( a = 0 - b; a <= (s32) atlas[i].width + b; ++a ) 947 for ( a = 0 - b; a <= (s32) atlas[i].width + b; ++a )
948 { 948 {
949 col[0] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), 0 ); 949 col[0] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), 0 );
950 col[1] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), atlas[i].height - 1 ); 950 col[1] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), atlas[i].height - 1 );
951 951
952 master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + ( b + 1 ) * -1, col[wrap[texmode][0]] ); 952 master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + ( b + 1 ) * -1, col[wrap[texmode][0]] );
953 master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + atlas[i].height - 1 + ( b + 1 ) * 1, col[wrap[texmode][1]] ); 953 master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + atlas[i].height - 1 + ( b + 1 ) * 1, col[wrap[texmode][1]] );
954 } 954 }
955 955
956 for ( a = -1 - b; a <= (s32) atlas[i].height + b; ++a ) 956 for ( a = -1 - b; a <= (s32) atlas[i].height + b; ++a )
957 { 957 {
958 col[0] = atlas[i].image->getPixel ( 0, core::s32_clamp ( a, 0, atlas[i].height - 1 ) ); 958 col[0] = atlas[i].image->getPixel ( 0, core::s32_clamp ( a, 0, atlas[i].height - 1 ) );
959 col[1] = atlas[i].image->getPixel ( atlas[i].width - 1, core::s32_clamp ( a, 0, atlas[i].height - 1 ) ); 959 col[1] = atlas[i].image->getPixel ( atlas[i].width - 1, core::s32_clamp ( a, 0, atlas[i].height - 1 ) );
960 960
961 master->setPixel ( atlas[i].pos.X + ( b + 1 ) * -1, atlas[i].pos.Y + a, col[wrap[texmode][0]] ); 961 master->setPixel ( atlas[i].pos.X + ( b + 1 ) * -1, atlas[i].pos.Y + a, col[wrap[texmode][0]] );
962 master->setPixel ( atlas[i].pos.X + atlas[i].width + b, atlas[i].pos.Y + a, col[wrap[texmode][1]] ); 962 master->setPixel ( atlas[i].pos.X + atlas[i].width + b, atlas[i].pos.Y + a, col[wrap[texmode][1]] );
963 } 963 }
964 } 964 }
965 } 965 }
966 966
967 addSource ( "_merged_", master ); 967 addSource ( "_merged_", master );
968 Master = master; 968 Master = master;
969} 969}
970 970
971 971
972/*! 972/*!
973*/ 973*/
974SHalflifeHeader* CAnimatedMeshHalfLife::loadModel(io::IReadFile* file, const io::path& filename) 974SHalflifeHeader* CAnimatedMeshHalfLife::loadModel(io::IReadFile* file, const io::path& filename)
975{ 975{
976 bool closefile = false; 976 bool closefile = false;
977 977
978 // if secondary files are needed, open here and mark for closing 978 // if secondary files are needed, open here and mark for closing
979 if ( 0 == file ) 979 if ( 0 == file )
980 { 980 {
981 file = SceneManager->getFileSystem()->createAndOpenFile(filename); 981 file = SceneManager->getFileSystem()->createAndOpenFile(filename);
982 closefile = true; 982 closefile = true;
983 } 983 }
984 984
985 if ( 0 == file ) 985 if ( 0 == file )
986 return 0; 986 return 0;
987 987
988 // read into memory 988 // read into memory
989 u8* pin = new u8[file->getSize()]; 989 u8* pin = new u8[file->getSize()];
990 file->read(pin, file->getSize()); 990 file->read(pin, file->getSize());
991 991
992 SHalflifeHeader* header = (SHalflifeHeader*) pin; 992 SHalflifeHeader* header = (SHalflifeHeader*) pin;
993 993
994 const bool idst = (0 == strncmp(header->id, "IDST", 4)); 994 const bool idst = (0 == strncmp(header->id, "IDST", 4));
995 const bool idsq = (0 == strncmp(header->id, "IDSQ", 4)); 995 const bool idsq = (0 == strncmp(header->id, "IDSQ", 4));
996 996
997 if ( (!idst && !idsq) || (idsq && !Header) ) 997 if ( (!idst && !idsq) || (idsq && !Header) )
998 { 998 {
999 os::Printer::log("MDL Halflife Loader: Wrong file header", file->getFileName(), ELL_WARNING); 999 os::Printer::log("MDL Halflife Loader: Wrong file header", file->getFileName(), ELL_WARNING);
1000 if ( closefile ) 1000 if ( closefile )
1001 { 1001 {
1002 file->drop(); 1002 file->drop();
1003 file = 0; 1003 file = 0;
1004 } 1004 }
1005 delete [] pin; 1005 delete [] pin;
1006 return 0; 1006 return 0;
1007 } 1007 }
1008 1008
1009 // don't know the real header.. idsg might be different 1009 // don't know the real header.. idsg might be different
1010 if (header->textureindex && idst ) 1010 if (header->textureindex && idst )
1011 { 1011 {
1012 io::path path; 1012 io::path path;
1013 io::path fname; 1013 io::path fname;
1014 io::path ext; 1014 io::path ext;
1015 1015
1016 core::splitFilename(file->getFileName(), &path, &fname, &ext); 1016 core::splitFilename(file->getFileName(), &path, &fname, &ext);
1017 TextureBaseName = path + fname + "_"; 1017 TextureBaseName = path + fname + "_";
1018 1018
1019 SHalflifeTexture *tex = (SHalflifeTexture *)(pin + header->textureindex); 1019 SHalflifeTexture *tex = (SHalflifeTexture *)(pin + header->textureindex);
1020 u32 *palette = new u32[256]; 1020 u32 *palette = new u32[256];
1021 for (u32 i = 0; i < header->numtextures; ++i) 1021 for (u32 i = 0; i < header->numtextures; ++i)
1022 { 1022 {
1023 const u8 *src = pin + tex[i].index; 1023 const u8 *src = pin + tex[i].index;
1024 1024
1025 // convert rgb to argb palette 1025 // convert rgb to argb palette
1026 { 1026 {
1027 const u8 *pal = src + tex[i].width * tex[i].height; 1027 const u8 *pal = src + tex[i].width * tex[i].height;
1028 for( u32 g=0; g<256; ++g ) 1028 for( u32 g=0; g<256; ++g )
1029 { 1029 {
1030 palette[g] = 0xFF000000 | pal[0] << 16 | pal[1] << 8 | pal[2]; 1030 palette[g] = 0xFF000000 | pal[0] << 16 | pal[1] << 8 | pal[2];
1031 pal += 3; 1031 pal += 3;
1032 } 1032 }
1033 } 1033 }
1034 1034
1035 IImage* image = SceneManager->getVideoDriver()->createImage(ECF_R8G8B8, core::dimension2d<u32>(tex[i].width, tex[i].height)); 1035 IImage* image = SceneManager->getVideoDriver()->createImage(ECF_R8G8B8, core::dimension2d<u32>(tex[i].width, tex[i].height));
1036 1036
1037 CColorConverter::convert8BitTo24Bit(src, (u8*)image->lock(), tex[i].width, tex[i].height, (u8*) palette, 0, false); 1037 CColorConverter::convert8BitTo24Bit(src, (u8*)image->lock(), tex[i].width, tex[i].height, (u8*) palette, 0, false);
1038 image->unlock(); 1038 image->unlock();
1039 1039
1040#ifdef HL_TEXTURE_ATLAS 1040#ifdef HL_TEXTURE_ATLAS
1041 TextureAtlas.addSource ( tex[i].name, image ); 1041 TextureAtlas.addSource ( tex[i].name, image );
1042#else 1042#else
1043 core::splitFilename ( tex[i].name, 0, &fname, &ext ); 1043 core::splitFilename ( tex[i].name, 0, &fname, &ext );
1044 SceneManager->getVideoDriver()->addTexture ( TextureBaseName + fname, image ); 1044 SceneManager->getVideoDriver()->addTexture ( TextureBaseName + fname, image );
1045 image->drop(); 1045 image->drop();
1046#endif 1046#endif
1047 } 1047 }
1048 delete [] palette; 1048 delete [] palette;
1049 1049
1050#ifdef HL_TEXTURE_ATLAS 1050#ifdef HL_TEXTURE_ATLAS
1051 TextureAtlas.create ( 2 * 2 + 1, ETC_CLAMP ); 1051 TextureAtlas.create ( 2 * 2 + 1, ETC_CLAMP );
1052 SceneManager->getVideoDriver()->addTexture ( TextureBaseName + "atlas", TextureAtlas.Master ); 1052 SceneManager->getVideoDriver()->addTexture ( TextureBaseName + "atlas", TextureAtlas.Master );
1053 TextureAtlas.release(); 1053 TextureAtlas.release();
1054#endif 1054#endif
1055 } 1055 }
1056 1056
1057 if (!Header) 1057 if (!Header)
1058 Header = header; 1058 Header = header;
1059 1059
1060 if ( closefile ) 1060 if ( closefile )
1061 { 1061 {
1062 file->drop(); 1062 file->drop();
1063 file = 0; 1063 file = 0;
1064 } 1064 }
1065 1065
1066 return header; 1066 return header;
1067} 1067}
1068 1068
1069 1069
1070/*! 1070/*!
1071*/ 1071*/
1072f32 CAnimatedMeshHalfLife::SetController( s32 controllerIndex, f32 value ) 1072f32 CAnimatedMeshHalfLife::SetController( s32 controllerIndex, f32 value )
1073{ 1073{
1074 if (!Header) 1074 if (!Header)
1075 return 0.f; 1075 return 0.f;
1076 1076
1077 SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex); 1077 SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex);
1078 1078
1079 // find first controller that matches the index 1079 // find first controller that matches the index
1080 u32 i; 1080 u32 i;
1081 for (i = 0; i < Header->numbonecontrollers; i++, bonecontroller++) 1081 for (i = 0; i < Header->numbonecontrollers; i++, bonecontroller++)
1082 { 1082 {
1083 if (bonecontroller->index == controllerIndex) 1083 if (bonecontroller->index == controllerIndex)
1084 break; 1084 break;
1085 } 1085 }
1086 if (i >= Header->numbonecontrollers) 1086 if (i >= Header->numbonecontrollers)
1087 return value; 1087 return value;
1088 1088
1089 // wrap 0..360 if it's a rotational controller 1089 // wrap 0..360 if it's a rotational controller
1090 if (bonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) 1090 if (bonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR))
1091 { 1091 {
1092 // ugly hack, invert value if end < start 1092 // ugly hack, invert value if end < start
1093 if (bonecontroller->end < bonecontroller->start) 1093 if (bonecontroller->end < bonecontroller->start)
1094 value = -value; 1094 value = -value;
1095 1095
1096 // does the controller not wrap? 1096 // does the controller not wrap?
1097 if (bonecontroller->start + 359.f >= bonecontroller->end) 1097 if (bonecontroller->start + 359.f >= bonecontroller->end)
1098 { 1098 {
1099 if (value > ((bonecontroller->start + bonecontroller->end) / 2.f) + 180.f) 1099 if (value > ((bonecontroller->start + bonecontroller->end) / 2.f) + 180.f)
1100 value = value - 360.f; 1100 value = value - 360.f;
1101 if (value < ((bonecontroller->start + bonecontroller->end) / 2.f) - 180.f) 1101 if (value < ((bonecontroller->start + bonecontroller->end) / 2.f) - 180.f)
1102 value = value + 360.f; 1102 value = value + 360.f;
1103 } 1103 }
1104 else 1104 else
1105 { 1105 {
1106 if (value > 360.f) 1106 if (value > 360.f)
1107 value = value - (s32)(value / 360.f) * 360.f; 1107 value = value - (s32)(value / 360.f) * 360.f;
1108 else if (value < 0.f) 1108 else if (value < 0.f)
1109 value = value + (s32)((value / -360.f) + 1) * 360.f; 1109 value = value + (s32)((value / -360.f) + 1) * 360.f;
1110 } 1110 }
1111 } 1111 }
1112 1112
1113 s32 range = controllerIndex == MOUTH_CONTROLLER ? 64 : 255; 1113 s32 range = controllerIndex == MOUTH_CONTROLLER ? 64 : 255;
1114 1114
1115 s32 setting = (s32) ( (f32) range * (value - bonecontroller->start) / (bonecontroller->end - bonecontroller->start)); 1115 s32 setting = (s32) ( (f32) range * (value - bonecontroller->start) / (bonecontroller->end - bonecontroller->start));
1116 1116
1117 if (setting < 0) setting = 0; 1117 if (setting < 0) setting = 0;
1118 if (setting > range) setting = range; 1118 if (setting > range) setting = range;
1119 1119
1120 BoneController[controllerIndex] = setting; 1120 BoneController[controllerIndex] = setting;
1121 1121
1122 return setting * (1.f / (f32) range ) * (bonecontroller->end - bonecontroller->start) + bonecontroller->start; 1122 return setting * (1.f / (f32) range ) * (bonecontroller->end - bonecontroller->start) + bonecontroller->start;
1123} 1123}
1124 1124
1125 1125
1126/*! 1126/*!
1127*/ 1127*/
1128u32 CAnimatedMeshHalfLife::SetSkin( u32 value ) 1128u32 CAnimatedMeshHalfLife::SetSkin( u32 value )
1129{ 1129{
1130 if (value < Header->numskinfamilies) 1130 if (value < Header->numskinfamilies)
1131 SkinGroupSelection = value; 1131 SkinGroupSelection = value;
1132 1132
1133 return SkinGroupSelection; 1133 return SkinGroupSelection;
1134} 1134}
1135 1135
1136 1136
1137/*! 1137/*!
1138*/ 1138*/
1139bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename ) 1139bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename )
1140{ 1140{
1141 io::path path; 1141 io::path path;
1142 io::path texname; 1142 io::path texname;
1143 io::path submodel; 1143 io::path submodel;
1144 1144
1145 core::splitFilename ( filename ,&path, &texname, 0 ); 1145 core::splitFilename ( filename ,&path, &texname, 0 );
1146 1146
1147 // preload textures 1147 // preload textures
1148 // if no textures are stored in main file, use texfile 1148 // if no textures are stored in main file, use texfile
1149 if (Header->numtextures == 0) 1149 if (Header->numtextures == 0)
1150 { 1150 {
1151 submodel = path + texname + "T.mdl"; 1151 submodel = path + texname + "T.mdl";
1152 TextureHeader = loadModel(0, submodel); 1152 TextureHeader = loadModel(0, submodel);
1153 if (!TextureHeader) 1153 if (!TextureHeader)
1154 return false; 1154 return false;
1155 OwnTexModel = true; 1155 OwnTexModel = true;
1156 } 1156 }
1157 else 1157 else
1158 { 1158 {
1159 TextureHeader = Header; 1159 TextureHeader = Header;
1160 OwnTexModel = false; 1160 OwnTexModel = false;
1161 } 1161 }
1162 1162
1163 // preload animations 1163 // preload animations
1164 if (Header->numseqgroups > 1) 1164 if (Header->numseqgroups > 1)
1165 { 1165 {
1166 c8 seq[8]; 1166 c8 seq[8];
1167 for (u32 i = 1; i < Header->numseqgroups; i++) 1167 for (u32 i = 1; i < Header->numseqgroups; i++)
1168 { 1168 {
1169 snprintf( seq, 8, "%02d.mdl", i ); 1169 snprintf( seq, 8, "%02d.mdl", i );
1170 submodel = path + texname + seq; 1170 submodel = path + texname + seq;
1171 1171
1172 AnimationHeader[i] = loadModel(0, submodel); 1172 AnimationHeader[i] = loadModel(0, submodel);
1173 if (!AnimationHeader[i]) 1173 if (!AnimationHeader[i])
1174 return false; 1174 return false;
1175 } 1175 }
1176 } 1176 }
1177 1177
1178 return true; 1178 return true;
1179} 1179}
1180 1180
1181 1181
1182/*! 1182/*!
1183*/ 1183*/
1184void CAnimatedMeshHalfLife::dumpModelInfo(u32 level) const 1184void CAnimatedMeshHalfLife::dumpModelInfo(u32 level) const
1185{ 1185{
1186 const u8 *phdr = (const u8*) Header; 1186 const u8 *phdr = (const u8*) Header;
1187 const SHalflifeHeader * hdr = Header; 1187 const SHalflifeHeader * hdr = Header;
1188 u32 i; 1188 u32 i;
1189 1189
1190 if (level == 0) 1190 if (level == 0)
1191 { 1191 {
1192 printf ( 1192 printf (
1193 "Bones: %d\n" 1193 "Bones: %d\n"
1194 "Bone Controllers: %d\n" 1194 "Bone Controllers: %d\n"
1195 "Hit Boxes: %d\n" 1195 "Hit Boxes: %d\n"
1196 "Sequences: %d\n" 1196 "Sequences: %d\n"
1197 "Sequence Groups: %d\n", 1197 "Sequence Groups: %d\n",
1198 hdr->numbones, 1198 hdr->numbones,
1199 hdr->numbonecontrollers, 1199 hdr->numbonecontrollers,
1200 hdr->numhitboxes, 1200 hdr->numhitboxes,
1201 hdr->numseq, 1201 hdr->numseq,
1202 hdr->numseqgroups 1202 hdr->numseqgroups
1203 ); 1203 );
1204 printf ( 1204 printf (
1205 "Textures: %d\n" 1205 "Textures: %d\n"
1206 "Skin Families: %d\n" 1206 "Skin Families: %d\n"
1207 "Bodyparts: %d\n" 1207 "Bodyparts: %d\n"
1208 "Attachments: %d\n" 1208 "Attachments: %d\n"
1209 "Transitions: %d\n", 1209 "Transitions: %d\n",
1210 hdr->numtextures, 1210 hdr->numtextures,
1211 hdr->numskinfamilies, 1211 hdr->numskinfamilies,
1212 hdr->numbodyparts, 1212 hdr->numbodyparts,
1213 hdr->numattachments, 1213 hdr->numattachments,
1214 hdr->numtransitions); 1214 hdr->numtransitions);
1215 return; 1215 return;
1216 } 1216 }
1217 1217
1218 printf("id: %c%c%c%c\n", phdr[0], phdr[1], phdr[2], phdr[3]); 1218 printf("id: %c%c%c%c\n", phdr[0], phdr[1], phdr[2], phdr[3]);
1219 printf("version: %d\n", hdr->version); 1219 printf("version: %d\n", hdr->version);
1220 printf("name: \"%s\"\n", hdr->name); 1220 printf("name: \"%s\"\n", hdr->name);
1221 printf("length: %d\n\n", hdr->length); 1221 printf("length: %d\n\n", hdr->length);
1222 1222
1223 printf("eyeposition: %f %f %f\n", hdr->eyeposition[0], hdr->eyeposition[1], hdr->eyeposition[2]); 1223 printf("eyeposition: %f %f %f\n", hdr->eyeposition[0], hdr->eyeposition[1], hdr->eyeposition[2]);
1224 printf("min: %f %f %f\n", hdr->min[0], hdr->min[1], hdr->min[2]); 1224 printf("min: %f %f %f\n", hdr->min[0], hdr->min[1], hdr->min[2]);
1225 printf("max: %f %f %f\n", hdr->max[0], hdr->max[1], hdr->max[2]); 1225 printf("max: %f %f %f\n", hdr->max[0], hdr->max[1], hdr->max[2]);
1226 printf("bbmin: %f %f %f\n", hdr->bbmin[0], hdr->bbmin[1], hdr->bbmin[2]); 1226 printf("bbmin: %f %f %f\n", hdr->bbmin[0], hdr->bbmin[1], hdr->bbmin[2]);
1227 printf("bbmax: %f %f %f\n", hdr->bbmax[0], hdr->bbmax[1], hdr->bbmax[2]); 1227 printf("bbmax: %f %f %f\n", hdr->bbmax[0], hdr->bbmax[1], hdr->bbmax[2]);
1228 1228
1229 printf("flags: %d\n\n", hdr->flags); 1229 printf("flags: %d\n\n", hdr->flags);
1230 1230
1231 printf("numbones: %d\n", hdr->numbones); 1231 printf("numbones: %d\n", hdr->numbones);
1232 for (i = 0; i < hdr->numbones; i++) 1232 for (i = 0; i < hdr->numbones; i++)
1233 { 1233 {
1234 const SHalflifeBone *bone = (const SHalflifeBone *) (phdr + hdr->boneindex); 1234 const SHalflifeBone *bone = (const SHalflifeBone *) (phdr + hdr->boneindex);
1235 printf("bone %d.name: \"%s\"\n", i + 1, bone[i].name); 1235 printf("bone %d.name: \"%s\"\n", i + 1, bone[i].name);
1236 printf("bone %d.parent: %d\n", i + 1, bone[i].parent); 1236 printf("bone %d.parent: %d\n", i + 1, bone[i].parent);
1237 printf("bone %d.flags: %d\n", i + 1, bone[i].flags); 1237 printf("bone %d.flags: %d\n", i + 1, bone[i].flags);
1238 printf("bone %d.bonecontroller: %d %d %d %d %d %d\n", i + 1, bone[i].bonecontroller[0], bone[i].bonecontroller[1], bone[i].bonecontroller[2], bone[i].bonecontroller[3], bone[i].bonecontroller[4], bone[i].bonecontroller[5]); 1238 printf("bone %d.bonecontroller: %d %d %d %d %d %d\n", i + 1, bone[i].bonecontroller[0], bone[i].bonecontroller[1], bone[i].bonecontroller[2], bone[i].bonecontroller[3], bone[i].bonecontroller[4], bone[i].bonecontroller[5]);
1239 printf("bone %d.value: %f %f %f %f %f %f\n", i + 1, bone[i].value[0], bone[i].value[1], bone[i].value[2], bone[i].value[3], bone[i].value[4], bone[i].value[5]); 1239 printf("bone %d.value: %f %f %f %f %f %f\n", i + 1, bone[i].value[0], bone[i].value[1], bone[i].value[2], bone[i].value[3], bone[i].value[4], bone[i].value[5]);
1240 printf("bone %d.scale: %f %f %f %f %f %f\n", i + 1, bone[i].scale[0], bone[i].scale[1], bone[i].scale[2], bone[i].scale[3], bone[i].scale[4], bone[i].scale[5]); 1240 printf("bone %d.scale: %f %f %f %f %f %f\n", i + 1, bone[i].scale[0], bone[i].scale[1], bone[i].scale[2], bone[i].scale[3], bone[i].scale[4], bone[i].scale[5]);
1241 } 1241 }
1242 1242
1243 printf("\nnumbonecontrollers: %d\n", hdr->numbonecontrollers); 1243 printf("\nnumbonecontrollers: %d\n", hdr->numbonecontrollers);
1244 const SHalflifeBoneController *bonecontrollers = (const SHalflifeBoneController *) (phdr + hdr->bonecontrollerindex); 1244 const SHalflifeBoneController *bonecontrollers = (const SHalflifeBoneController *) (phdr + hdr->bonecontrollerindex);
1245 for (i = 0; i < hdr->numbonecontrollers; i++) 1245 for (i = 0; i < hdr->numbonecontrollers; i++)
1246 { 1246 {
1247 printf("bonecontroller %d.bone: %d\n", i + 1, bonecontrollers[i].bone); 1247 printf("bonecontroller %d.bone: %d\n", i + 1, bonecontrollers[i].bone);
1248 printf("bonecontroller %d.type: %d\n", i + 1, bonecontrollers[i].type); 1248 printf("bonecontroller %d.type: %d\n", i + 1, bonecontrollers[i].type);
1249 printf("bonecontroller %d.start: %f\n", i + 1, bonecontrollers[i].start); 1249 printf("bonecontroller %d.start: %f\n", i + 1, bonecontrollers[i].start);
1250 printf("bonecontroller %d.end: %f\n", i + 1, bonecontrollers[i].end); 1250 printf("bonecontroller %d.end: %f\n", i + 1, bonecontrollers[i].end);
1251 printf("bonecontroller %d.rest: %d\n", i + 1, bonecontrollers[i].rest); 1251 printf("bonecontroller %d.rest: %d\n", i + 1, bonecontrollers[i].rest);
1252 printf("bonecontroller %d.index: %d\n", i + 1, bonecontrollers[i].index); 1252 printf("bonecontroller %d.index: %d\n", i + 1, bonecontrollers[i].index);
1253 } 1253 }
1254 1254
1255 printf("\nnumhitboxes: %d\n", hdr->numhitboxes); 1255 printf("\nnumhitboxes: %d\n", hdr->numhitboxes);
1256 const SHalflifeBBox *box = (const SHalflifeBBox *) (phdr + hdr->hitboxindex); 1256 const SHalflifeBBox *box = (const SHalflifeBBox *) (phdr + hdr->hitboxindex);
1257 for (i = 0; i < hdr->numhitboxes; i++) 1257 for (i = 0; i < hdr->numhitboxes; i++)
1258 { 1258 {
1259 printf("hitbox %d.bone: %d\n", i + 1, box[i].bone); 1259 printf("hitbox %d.bone: %d\n", i + 1, box[i].bone);
1260 printf("hitbox %d.group: %d\n", i + 1, box[i].group); 1260 printf("hitbox %d.group: %d\n", i + 1, box[i].group);
1261 printf("hitbox %d.bbmin: %f %f %f\n", i + 1, box[i].bbmin[0], box[i].bbmin[1], box[i].bbmin[2]); 1261 printf("hitbox %d.bbmin: %f %f %f\n", i + 1, box[i].bbmin[0], box[i].bbmin[1], box[i].bbmin[2]);
1262 printf("hitbox %d.bbmax: %f %f %f\n", i + 1, box[i].bbmax[0], box[i].bbmax[1], box[i].bbmax[2]); 1262 printf("hitbox %d.bbmax: %f %f %f\n", i + 1, box[i].bbmax[0], box[i].bbmax[1], box[i].bbmax[2]);
1263 } 1263 }
1264 1264
1265 printf("\nnumseq: %d\n", hdr->numseq); 1265 printf("\nnumseq: %d\n", hdr->numseq);
1266 const SHalflifeSequence *seq = (const SHalflifeSequence *) (phdr + hdr->seqindex); 1266 const SHalflifeSequence *seq = (const SHalflifeSequence *) (phdr + hdr->seqindex);
1267 for (i = 0; i < hdr->numseq; i++) 1267 for (i = 0; i < hdr->numseq; i++)
1268 { 1268 {
1269 printf("seqdesc %d.label: \"%s\"\n", i + 1, seq[i].label); 1269 printf("seqdesc %d.label: \"%s\"\n", i + 1, seq[i].label);
1270 printf("seqdesc %d.fps: %f\n", i + 1, seq[i].fps); 1270 printf("seqdesc %d.fps: %f\n", i + 1, seq[i].fps);
1271 printf("seqdesc %d.flags: %d\n", i + 1, seq[i].flags); 1271 printf("seqdesc %d.flags: %d\n", i + 1, seq[i].flags);
1272 printf("<...>\n"); 1272 printf("<...>\n");
1273 } 1273 }
1274 1274
1275 printf("\nnumseqgroups: %d\n", hdr->numseqgroups); 1275 printf("\nnumseqgroups: %d\n", hdr->numseqgroups);
1276 for (i = 0; i < hdr->numseqgroups; i++) 1276 for (i = 0; i < hdr->numseqgroups; i++)
1277 { 1277 {
1278 const SHalflifeSequenceGroup *group = (const SHalflifeSequenceGroup *) (phdr + hdr->seqgroupindex); 1278 const SHalflifeSequenceGroup *group = (const SHalflifeSequenceGroup *) (phdr + hdr->seqgroupindex);
1279 printf("\nseqgroup %d.label: \"%s\"\n", i + 1, group[i].label); 1279 printf("\nseqgroup %d.label: \"%s\"\n", i + 1, group[i].label);
1280 printf("\nseqgroup %d.namel: \"%s\"\n", i + 1, group[i].name); 1280 printf("\nseqgroup %d.namel: \"%s\"\n", i + 1, group[i].name);
1281 printf("\nseqgroup %d.data: %d\n", i + 1, group[i].data); 1281 printf("\nseqgroup %d.data: %d\n", i + 1, group[i].data);
1282 } 1282 }
1283 1283
1284 printf("\nnumskinref: %d\n", hdr->numskinref); 1284 printf("\nnumskinref: %d\n", hdr->numskinref);
1285 printf("numskinfamilies: %d\n", hdr->numskinfamilies); 1285 printf("numskinfamilies: %d\n", hdr->numskinfamilies);
1286 1286
1287 printf("\nnumbodyparts: %d\n", hdr->numbodyparts); 1287 printf("\nnumbodyparts: %d\n", hdr->numbodyparts);
1288 const SHalflifeBody *pbodyparts = (const SHalflifeBody*) ((const u8*) hdr + hdr->bodypartindex); 1288 const SHalflifeBody *pbodyparts = (const SHalflifeBody*) ((const u8*) hdr + hdr->bodypartindex);
1289 for (i = 0; i < hdr->numbodyparts; i++) 1289 for (i = 0; i < hdr->numbodyparts; i++)
1290 { 1290 {
1291 printf("bodypart %d.name: \"%s\"\n", i + 1, pbodyparts[i].name); 1291 printf("bodypart %d.name: \"%s\"\n", i + 1, pbodyparts[i].name);
1292 printf("bodypart %d.nummodels: %d\n", i + 1, pbodyparts[i].nummodels); 1292 printf("bodypart %d.nummodels: %d\n", i + 1, pbodyparts[i].nummodels);
1293 printf("bodypart %d.base: %d\n", i + 1, pbodyparts[i].base); 1293 printf("bodypart %d.base: %d\n", i + 1, pbodyparts[i].base);
1294 printf("bodypart %d.modelindex: %d\n", i + 1, pbodyparts[i].modelindex); 1294 printf("bodypart %d.modelindex: %d\n", i + 1, pbodyparts[i].modelindex);
1295 } 1295 }
1296 1296
1297 printf("\nnumattachments: %d\n", hdr->numattachments); 1297 printf("\nnumattachments: %d\n", hdr->numattachments);
1298 for (i = 0; i < hdr->numattachments; i++) 1298 for (i = 0; i < hdr->numattachments; i++)
1299 { 1299 {
1300 const SHalflifeAttachment *attach = (const SHalflifeAttachment *) ((const u8*) hdr + hdr->attachmentindex); 1300 const SHalflifeAttachment *attach = (const SHalflifeAttachment *) ((const u8*) hdr + hdr->attachmentindex);
1301 printf("attachment %d.name: \"%s\"\n", i + 1, attach[i].name); 1301 printf("attachment %d.name: \"%s\"\n", i + 1, attach[i].name);
1302 } 1302 }
1303 1303
1304 hdr = TextureHeader; 1304 hdr = TextureHeader;
1305 printf("\nnumtextures: %d\n", hdr->numtextures); 1305 printf("\nnumtextures: %d\n", hdr->numtextures);
1306 printf("textureindex: %d\n", hdr->textureindex); 1306 printf("textureindex: %d\n", hdr->textureindex);
1307 printf("texturedataindex: %d\n", hdr->texturedataindex); 1307 printf("texturedataindex: %d\n", hdr->texturedataindex);
1308 const SHalflifeTexture *ptextures = (const SHalflifeTexture *) ((const u8*) hdr + hdr->textureindex); 1308 const SHalflifeTexture *ptextures = (const SHalflifeTexture *) ((const u8*) hdr + hdr->textureindex);
1309 for (i = 0; i < hdr->numtextures; i++) 1309 for (i = 0; i < hdr->numtextures; i++)
1310 { 1310 {
1311 printf("texture %d.name: \"%s\"\n", i + 1, ptextures[i].name); 1311 printf("texture %d.name: \"%s\"\n", i + 1, ptextures[i].name);
1312 printf("texture %d.flags: %d\n", i + 1, ptextures[i].flags); 1312 printf("texture %d.flags: %d\n", i + 1, ptextures[i].flags);
1313 printf("texture %d.width: %d\n", i + 1, ptextures[i].width); 1313 printf("texture %d.width: %d\n", i + 1, ptextures[i].width);
1314 printf("texture %d.height: %d\n", i + 1, ptextures[i].height); 1314 printf("texture %d.height: %d\n", i + 1, ptextures[i].height);
1315 printf("texture %d.index: %d\n", i + 1, ptextures[i].index); 1315 printf("texture %d.index: %d\n", i + 1, ptextures[i].index);
1316 } 1316 }
1317} 1317}
1318 1318
1319 1319
1320/*! 1320/*!
1321*/ 1321*/
1322void CAnimatedMeshHalfLife::ExtractBbox(s32 sequence, core::aabbox3df &box) const 1322void CAnimatedMeshHalfLife::ExtractBbox(s32 sequence, core::aabbox3df &box) const
1323{ 1323{
1324 const SHalflifeSequence *seq = (const SHalflifeSequence *)((const u8*)Header + Header->seqindex) + sequence; 1324 const SHalflifeSequence *seq = (const SHalflifeSequence *)((const u8*)Header + Header->seqindex) + sequence;
1325 1325
1326 box.MinEdge.X = seq[0].bbmin[0]; 1326 box.MinEdge.X = seq[0].bbmin[0];
1327 box.MinEdge.Y = seq[0].bbmin[1]; 1327 box.MinEdge.Y = seq[0].bbmin[1];
1328 box.MinEdge.Z = seq[0].bbmin[2]; 1328 box.MinEdge.Z = seq[0].bbmin[2];
1329 1329
1330 box.MaxEdge.X = seq[0].bbmax[0]; 1330 box.MaxEdge.X = seq[0].bbmax[0];
1331 box.MaxEdge.Y = seq[0].bbmax[1]; 1331 box.MaxEdge.Y = seq[0].bbmax[1];
1332 box.MaxEdge.Z = seq[0].bbmax[2]; 1332 box.MaxEdge.Z = seq[0].bbmax[2];
1333} 1333}
1334 1334
1335 1335
1336/*! 1336/*!
1337*/ 1337*/
1338void CAnimatedMeshHalfLife::calcBoneAdj() 1338void CAnimatedMeshHalfLife::calcBoneAdj()
1339{ 1339{
1340 const SHalflifeBoneController *bonecontroller = 1340 const SHalflifeBoneController *bonecontroller =
1341 (const SHalflifeBoneController *)((const u8*) Header + Header->bonecontrollerindex); 1341 (const SHalflifeBoneController *)((const u8*) Header + Header->bonecontrollerindex);
1342 1342
1343 for (u32 j = 0; j < Header->numbonecontrollers; j++) 1343 for (u32 j = 0; j < Header->numbonecontrollers; j++)
1344 { 1344 {
1345 const s32 i = bonecontroller[j].index; 1345 const s32 i = bonecontroller[j].index;
1346 // check for 360% wrapping 1346 // check for 360% wrapping
1347 f32 value; 1347 f32 value;
1348 if (bonecontroller[j].type & STUDIO_RLOOP) 1348 if (bonecontroller[j].type & STUDIO_RLOOP)
1349 { 1349 {
1350 value = BoneController[i] * (360.f/256.f) + bonecontroller[j].start; 1350 value = BoneController[i] * (360.f/256.f) + bonecontroller[j].start;
1351 } 1351 }
1352 else 1352 else
1353 { 1353 {
1354 const f32 range = i <= 3 ? 255.f : 64.f; 1354 const f32 range = i <= 3 ? 255.f : 64.f;
1355 value = core::clamp(BoneController[i] / range,0.f,1.f); 1355 value = core::clamp(BoneController[i] / range,0.f,1.f);
1356 value = (1.f - value) * bonecontroller[j].start + value * bonecontroller[j].end; 1356 value = (1.f - value) * bonecontroller[j].start + value * bonecontroller[j].end;
1357 } 1357 }
1358 1358
1359 switch(bonecontroller[j].type & STUDIO_TYPES) 1359 switch(bonecontroller[j].type & STUDIO_TYPES)
1360 { 1360 {
1361 case STUDIO_XR: 1361 case STUDIO_XR:
1362 case STUDIO_YR: 1362 case STUDIO_YR:
1363 case STUDIO_ZR: 1363 case STUDIO_ZR:
1364 BoneAdj[j] = value * core::DEGTORAD; 1364 BoneAdj[j] = value * core::DEGTORAD;
1365 break; 1365 break;
1366 case STUDIO_X: 1366 case STUDIO_X:
1367 case STUDIO_Y: 1367 case STUDIO_Y:
1368 case STUDIO_Z: 1368 case STUDIO_Z:
1369 BoneAdj[j] = value; 1369 BoneAdj[j] = value;
1370 break; 1370 break;
1371 } 1371 }
1372 } 1372 }
1373} 1373}
1374 1374
1375 1375
1376/*! 1376/*!
1377*/ 1377*/
1378void CAnimatedMeshHalfLife::calcBoneQuaternion(const s32 frame, const SHalflifeBone * const bone, 1378void CAnimatedMeshHalfLife::calcBoneQuaternion(const s32 frame, const SHalflifeBone * const bone,
1379 SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const 1379 SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const
1380{ 1380{
1381 // three vector components 1381 // three vector components
1382 if (anim->offset[j+3] == 0) 1382 if (anim->offset[j+3] == 0)
1383 { 1383 {
1384 angle2 = angle1 = bone->value[j+3]; // default 1384 angle2 = angle1 = bone->value[j+3]; // default
1385 } 1385 }
1386 else 1386 else
1387 { 1387 {
1388 SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j+3]); 1388 SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j+3]);
1389 s32 k = frame; 1389 s32 k = frame;
1390 while (animvalue->num.total <= k) 1390 while (animvalue->num.total <= k)
1391 { 1391 {
1392 k -= animvalue->num.total; 1392 k -= animvalue->num.total;
1393 animvalue += animvalue->num.valid + 1; 1393 animvalue += animvalue->num.valid + 1;
1394 } 1394 }
1395 // Bah, missing blend! 1395 // Bah, missing blend!
1396 if (animvalue->num.valid > k) 1396 if (animvalue->num.valid > k)
1397 { 1397 {
1398 angle1 = animvalue[k+1].value; 1398 angle1 = animvalue[k+1].value;
1399 1399
1400 if (animvalue->num.valid > k + 1) 1400 if (animvalue->num.valid > k + 1)
1401 { 1401 {
1402 angle2 = animvalue[k+2].value; 1402 angle2 = animvalue[k+2].value;
1403 } 1403 }
1404 else 1404 else
1405 { 1405 {
1406 if (animvalue->num.total > k + 1) 1406 if (animvalue->num.total > k + 1)
1407 angle2 = angle1; 1407 angle2 = angle1;
1408 else 1408 else
1409 angle2 = animvalue[animvalue->num.valid+2].value; 1409 angle2 = animvalue[animvalue->num.valid+2].value;
1410 } 1410 }
1411 } 1411 }
1412 else 1412 else
1413 { 1413 {
1414 angle1 = animvalue[animvalue->num.valid].value; 1414 angle1 = animvalue[animvalue->num.valid].value;
1415 if (animvalue->num.total > k + 1) 1415 if (animvalue->num.total > k + 1)
1416 { 1416 {
1417 angle2 = angle1; 1417 angle2 = angle1;
1418 } 1418 }
1419 else 1419 else
1420 { 1420 {
1421 angle2 = animvalue[animvalue->num.valid + 2].value; 1421 angle2 = animvalue[animvalue->num.valid + 2].value;
1422 } 1422 }
1423 } 1423 }
1424 angle1 = bone->value[j+3] + angle1 * bone->scale[j+3]; 1424 angle1 = bone->value[j+3] + angle1 * bone->scale[j+3];
1425 angle2 = bone->value[j+3] + angle2 * bone->scale[j+3]; 1425 angle2 = bone->value[j+3] + angle2 * bone->scale[j+3];
1426 } 1426 }
1427 1427
1428 if (bone->bonecontroller[j+3] != -1) 1428 if (bone->bonecontroller[j+3] != -1)
1429 { 1429 {
1430 angle1 += BoneAdj[bone->bonecontroller[j+3]]; 1430 angle1 += BoneAdj[bone->bonecontroller[j+3]];
1431 angle2 += BoneAdj[bone->bonecontroller[j+3]]; 1431 angle2 += BoneAdj[bone->bonecontroller[j+3]];
1432 } 1432 }
1433} 1433}
1434 1434
1435 1435
1436/*! 1436/*!
1437*/ 1437*/
1438void CAnimatedMeshHalfLife::calcBonePosition(const s32 frame, f32 s, 1438void CAnimatedMeshHalfLife::calcBonePosition(const s32 frame, f32 s,
1439 const SHalflifeBone * const bone, SHalflifeAnimOffset *anim, f32 *pos) const 1439 const SHalflifeBone * const bone, SHalflifeAnimOffset *anim, f32 *pos) const
1440{ 1440{
1441 for (s32 j = 0; j < 3; ++j) 1441 for (s32 j = 0; j < 3; ++j)
1442 { 1442 {
1443 pos[j] = bone->value[j]; // default; 1443 pos[j] = bone->value[j]; // default;
1444 if (anim->offset[j] != 0) 1444 if (anim->offset[j] != 0)
1445 { 1445 {
1446 SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j]); 1446 SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j]);
1447 1447
1448 s32 k = frame; 1448 s32 k = frame;
1449 // find span of values that includes the frame we want 1449 // find span of values that includes the frame we want
1450 while (animvalue->num.total <= k) 1450 while (animvalue->num.total <= k)
1451 { 1451 {
1452 k -= animvalue->num.total; 1452 k -= animvalue->num.total;
1453 animvalue += animvalue->num.valid + 1; 1453 animvalue += animvalue->num.valid + 1;
1454 } 1454 }
1455 // if we're inside the span 1455 // if we're inside the span
1456 if (animvalue->num.valid > k) 1456 if (animvalue->num.valid > k)
1457 { 1457 {
1458 // and there's more data in the span 1458 // and there's more data in the span
1459 if (animvalue->num.valid > k + 1) 1459 if (animvalue->num.valid > k + 1)
1460 { 1460 {
1461 pos[j] += (animvalue[k+1].value * (1.f - s) + s * animvalue[k+2].value) * bone->scale[j]; 1461 pos[j] += (animvalue[k+1].value * (1.f - s) + s * animvalue[k+2].value) * bone->scale[j];
1462 } 1462 }
1463 else 1463 else
1464 { 1464 {
1465 pos[j] += animvalue[k+1].value * bone->scale[j]; 1465 pos[j] += animvalue[k+1].value * bone->scale[j];
1466 } 1466 }
1467 } 1467 }
1468 else 1468 else
1469 { 1469 {
1470 // are we at the end of the repeating values section and there's another section with data? 1470 // are we at the end of the repeating values section and there's another section with data?
1471 if (animvalue->num.total <= k + 1) 1471 if (animvalue->num.total <= k + 1)
1472 { 1472 {
1473 pos[j] += (animvalue[animvalue->num.valid].value * (1.f - s) + s * animvalue[animvalue->num.valid + 2].value) * bone->scale[j]; 1473 pos[j] += (animvalue[animvalue->num.valid].value * (1.f - s) + s * animvalue[animvalue->num.valid + 2].value) * bone->scale[j];
1474 } 1474 }
1475 else 1475 else
1476 { 1476 {
1477 pos[j] += animvalue[animvalue->num.valid].value * bone->scale[j]; 1477 pos[j] += animvalue[animvalue->num.valid].value * bone->scale[j];
1478 } 1478 }
1479 } 1479 }
1480 } 1480 }
1481 if (bone->bonecontroller[j] != -1) 1481 if (bone->bonecontroller[j] != -1)
1482 { 1482 {
1483 pos[j] += BoneAdj[bone->bonecontroller[j]]; 1483 pos[j] += BoneAdj[bone->bonecontroller[j]];
1484 } 1484 }
1485 } 1485 }
1486} 1486}
1487 1487
1488 1488
1489/*! 1489/*!
1490*/ 1490*/
1491void CAnimatedMeshHalfLife::calcRotations(vec3_hl *pos, vec4_hl *q, 1491void CAnimatedMeshHalfLife::calcRotations(vec3_hl *pos, vec4_hl *q,
1492 SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f) 1492 SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f)
1493{ 1493{
1494 s32 frame = (s32)f; 1494 s32 frame = (s32)f;
1495 f32 s = (f - frame); 1495 f32 s = (f - frame);
1496 1496
1497 // add in programatic controllers 1497 // add in programatic controllers
1498 calcBoneAdj(); 1498 calcBoneAdj();
1499 1499
1500 SHalflifeBone *bone = (SHalflifeBone *)((u8 *)Header + Header->boneindex); 1500 SHalflifeBone *bone = (SHalflifeBone *)((u8 *)Header + Header->boneindex);
1501 for ( u32 i = 0; i < Header->numbones; i++, bone++, anim++) 1501 for ( u32 i = 0; i < Header->numbones; i++, bone++, anim++)
1502 { 1502 {
1503 core::vector3df angle1, angle2; 1503 core::vector3df angle1, angle2;
1504 calcBoneQuaternion(frame, bone, anim, 0, angle1.X, angle2.X); 1504 calcBoneQuaternion(frame, bone, anim, 0, angle1.X, angle2.X);
1505 calcBoneQuaternion(frame, bone, anim, 1, angle1.Y, angle2.Y); 1505 calcBoneQuaternion(frame, bone, anim, 1, angle1.Y, angle2.Y);
1506 calcBoneQuaternion(frame, bone, anim, 2, angle1.Z, angle2.Z); 1506 calcBoneQuaternion(frame, bone, anim, 2, angle1.Z, angle2.Z);
1507 1507
1508 if (!angle1.equals(angle2)) 1508 if (!angle1.equals(angle2))
1509 { 1509 {
1510 vec4_hl q1, q2; 1510 vec4_hl q1, q2;
1511 AngleQuaternion( angle1, q1 ); 1511 AngleQuaternion( angle1, q1 );
1512 AngleQuaternion( angle2, q2 ); 1512 AngleQuaternion( angle2, q2 );
1513 QuaternionSlerp( q1, q2, s, q[i] ); 1513 QuaternionSlerp( q1, q2, s, q[i] );
1514 } 1514 }
1515 else 1515 else
1516 { 1516 {
1517 AngleQuaternion( angle1, q[i] ); 1517 AngleQuaternion( angle1, q[i] );
1518 } 1518 }
1519 1519
1520 calcBonePosition(frame, s, bone, anim, pos[i]); 1520 calcBonePosition(frame, s, bone, anim, pos[i]);
1521 } 1521 }
1522 1522
1523 if (seq->motiontype & STUDIO_X) 1523 if (seq->motiontype & STUDIO_X)
1524 pos[seq->motionbone][0] = 0.f; 1524 pos[seq->motionbone][0] = 0.f;
1525 if (seq->motiontype & STUDIO_Y) 1525 if (seq->motiontype & STUDIO_Y)
1526 pos[seq->motionbone][1] = 0.f; 1526 pos[seq->motionbone][1] = 0.f;
1527 if (seq->motiontype & STUDIO_Z) 1527 if (seq->motiontype & STUDIO_Z)
1528 pos[seq->motionbone][2] = 0.f; 1528 pos[seq->motionbone][2] = 0.f;
1529} 1529}
1530 1530
1531 1531
1532/*! 1532/*!
1533*/ 1533*/
1534SHalflifeAnimOffset * CAnimatedMeshHalfLife::getAnim( SHalflifeSequence *seq ) 1534SHalflifeAnimOffset * CAnimatedMeshHalfLife::getAnim( SHalflifeSequence *seq )
1535{ 1535{
1536 SHalflifeSequenceGroup *seqgroup = (SHalflifeSequenceGroup *)((u8*)Header + Header->seqgroupindex) + seq->seqgroup; 1536 SHalflifeSequenceGroup *seqgroup = (SHalflifeSequenceGroup *)((u8*)Header + Header->seqgroupindex) + seq->seqgroup;
1537 1537
1538 if (seq->seqgroup == 0) 1538 if (seq->seqgroup == 0)
1539 { 1539 {
1540 return (SHalflifeAnimOffset *)((u8*)Header + seqgroup->data + seq->animindex); 1540 return (SHalflifeAnimOffset *)((u8*)Header + seqgroup->data + seq->animindex);
1541 } 1541 }
1542 1542
1543 return (SHalflifeAnimOffset *)((u8*)AnimationHeader[seq->seqgroup] + seq->animindex); 1543 return (SHalflifeAnimOffset *)((u8*)AnimationHeader[seq->seqgroup] + seq->animindex);
1544} 1544}
1545 1545
1546 1546
1547/*! 1547/*!
1548*/ 1548*/
1549void CAnimatedMeshHalfLife::slerpBones(vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s) 1549void CAnimatedMeshHalfLife::slerpBones(vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s)
1550{ 1550{
1551 if (s < 0) 1551 if (s < 0)
1552 s = 0; 1552 s = 0;
1553 else if (s > 1.f) 1553 else if (s > 1.f)
1554 s = 1.f; 1554 s = 1.f;
1555 1555
1556 f32 s1 = 1.f - s; 1556 f32 s1 = 1.f - s;
1557 1557
1558 for ( u32 i = 0; i < Header->numbones; i++) 1558 for ( u32 i = 0; i < Header->numbones; i++)
1559 { 1559 {
1560 vec4_hl q3; 1560 vec4_hl q3;
1561 QuaternionSlerp( q1[i], q2[i], s, q3 ); 1561 QuaternionSlerp( q1[i], q2[i], s, q3 );
1562 q1[i][0] = q3[0]; 1562 q1[i][0] = q3[0];
1563 q1[i][1] = q3[1]; 1563 q1[i][1] = q3[1];
1564 q1[i][2] = q3[2]; 1564 q1[i][2] = q3[2];
1565 q1[i][3] = q3[3]; 1565 q1[i][3] = q3[3];
1566 pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s; 1566 pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s;
1567 pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s; 1567 pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s;
1568 pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s; 1568 pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s;
1569 } 1569 }
1570} 1570}
1571 1571
1572 1572
1573/*! 1573/*!
1574*/ 1574*/
1575void CAnimatedMeshHalfLife::setUpBones() 1575void CAnimatedMeshHalfLife::setUpBones()
1576{ 1576{
1577 static vec3_hl pos[MAXSTUDIOBONES]; 1577 static vec3_hl pos[MAXSTUDIOBONES];
1578 f32 bonematrix[3][4]; 1578 f32 bonematrix[3][4];
1579 static vec4_hl q[MAXSTUDIOBONES]; 1579 static vec4_hl q[MAXSTUDIOBONES];
1580 1580
1581 static vec3_hl pos2[MAXSTUDIOBONES]; 1581 static vec3_hl pos2[MAXSTUDIOBONES];
1582 static vec4_hl q2[MAXSTUDIOBONES]; 1582 static vec4_hl q2[MAXSTUDIOBONES];
1583 static vec3_hl pos3[MAXSTUDIOBONES]; 1583 static vec3_hl pos3[MAXSTUDIOBONES];
1584 static vec4_hl q3[MAXSTUDIOBONES]; 1584 static vec4_hl q3[MAXSTUDIOBONES];
1585 static vec3_hl pos4[MAXSTUDIOBONES]; 1585 static vec3_hl pos4[MAXSTUDIOBONES];
1586 static vec4_hl q4[MAXSTUDIOBONES]; 1586 static vec4_hl q4[MAXSTUDIOBONES];
1587 1587
1588 if (SequenceIndex >= Header->numseq) 1588 if (SequenceIndex >= Header->numseq)
1589 SequenceIndex = 0; 1589 SequenceIndex = 0;
1590 1590
1591 SHalflifeSequence *seq = (SHalflifeSequence *)((u8*) Header + Header->seqindex) + SequenceIndex; 1591 SHalflifeSequence *seq = (SHalflifeSequence *)((u8*) Header + Header->seqindex) + SequenceIndex;
1592 1592
1593 SHalflifeAnimOffset *anim = getAnim(seq); 1593 SHalflifeAnimOffset *anim = getAnim(seq);
1594 calcRotations(pos, q, seq, anim, CurrentFrame); 1594 calcRotations(pos, q, seq, anim, CurrentFrame);
1595 1595
1596 if (seq->numblends > 1) 1596 if (seq->numblends > 1)
1597 { 1597 {
1598 anim += Header->numbones; 1598 anim += Header->numbones;
1599 calcRotations( pos2, q2, seq, anim, CurrentFrame ); 1599 calcRotations( pos2, q2, seq, anim, CurrentFrame );
1600 f32 s = Blending[0] / 255.f; 1600 f32 s = Blending[0] / 255.f;
1601 1601
1602 slerpBones( q, pos, q2, pos2, s ); 1602 slerpBones( q, pos, q2, pos2, s );
1603 1603
1604 if (seq->numblends == 4) 1604 if (seq->numblends == 4)
1605 { 1605 {
1606 anim += Header->numbones; 1606 anim += Header->numbones;
1607 calcRotations( pos3, q3, seq, anim, CurrentFrame ); 1607 calcRotations( pos3, q3, seq, anim, CurrentFrame );
1608 1608
1609 anim += Header->numbones; 1609 anim += Header->numbones;
1610 calcRotations( pos4, q4, seq, anim, CurrentFrame ); 1610 calcRotations( pos4, q4, seq, anim, CurrentFrame );
1611 1611
1612 s = Blending[0] / 255.f; 1612 s = Blending[0] / 255.f;
1613 slerpBones( q3, pos3, q4, pos4, s ); 1613 slerpBones( q3, pos3, q4, pos4, s );
1614 1614
1615 s = Blending[1] / 255.f; 1615 s = Blending[1] / 255.f;
1616 slerpBones( q, pos, q3, pos3, s ); 1616 slerpBones( q, pos, q3, pos3, s );
1617 } 1617 }
1618 } 1618 }
1619 1619
1620 SHalflifeBone *bone = (SHalflifeBone *)((u8*) Header + Header->boneindex); 1620 SHalflifeBone *bone = (SHalflifeBone *)((u8*) Header + Header->boneindex);
1621 1621
1622 for (u32 i = 0; i < Header->numbones; i++) 1622 for (u32 i = 0; i < Header->numbones; i++)
1623 { 1623 {
1624 QuaternionMatrix( q[i], bonematrix ); 1624 QuaternionMatrix( q[i], bonematrix );
1625 1625
1626 bonematrix[0][3] = pos[i][0]; 1626 bonematrix[0][3] = pos[i][0];
1627 bonematrix[1][3] = pos[i][1]; 1627 bonematrix[1][3] = pos[i][1];
1628 bonematrix[2][3] = pos[i][2]; 1628 bonematrix[2][3] = pos[i][2];
1629 1629
1630 if (bone[i].parent == -1) { 1630 if (bone[i].parent == -1) {
1631 memcpy(BoneTransform[i], bonematrix, sizeof(f32) * 12); 1631 memcpy(BoneTransform[i], bonematrix, sizeof(f32) * 12);
1632 } 1632 }
1633 else { 1633 else {
1634 R_ConcatTransforms (BoneTransform[bone[i].parent], bonematrix, BoneTransform[i]); 1634 R_ConcatTransforms (BoneTransform[bone[i].parent], bonematrix, BoneTransform[i]);
1635 } 1635 }
1636 } 1636 }
1637} 1637}
1638 1638
1639 1639
1640//! Returns an axis aligned bounding box 1640//! Returns an axis aligned bounding box
1641const core::aabbox3d<f32>& CAnimatedMeshHalfLife::getBoundingBox() const 1641const core::aabbox3d<f32>& CAnimatedMeshHalfLife::getBoundingBox() const
1642{ 1642{
1643 return MeshIPol->BoundingBox; 1643 return MeshIPol->BoundingBox;
1644} 1644}
1645 1645
1646 1646
1647//! Returns the type of the animated mesh. 1647//! Returns the type of the animated mesh.
1648E_ANIMATED_MESH_TYPE CAnimatedMeshHalfLife::getMeshType() const 1648E_ANIMATED_MESH_TYPE CAnimatedMeshHalfLife::getMeshType() const
1649{ 1649{
1650 return EAMT_MDL_HALFLIFE; 1650 return EAMT_MDL_HALFLIFE;
1651} 1651}
1652 1652
1653 1653
1654//! returns amount of mesh buffers. 1654//! returns amount of mesh buffers.
1655u32 CAnimatedMeshHalfLife::getMeshBufferCount() const 1655u32 CAnimatedMeshHalfLife::getMeshBufferCount() const
1656{ 1656{
1657 return MeshIPol->getMeshBufferCount(); 1657 return MeshIPol->getMeshBufferCount();
1658} 1658}
1659 1659
1660 1660
1661//! returns pointer to a mesh buffer 1661//! returns pointer to a mesh buffer
1662IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(u32 nr) const 1662IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(u32 nr) const
1663{ 1663{
1664 return MeshIPol->getMeshBuffer(nr); 1664 return MeshIPol->getMeshBuffer(nr);
1665} 1665}
1666 1666
1667 1667
1668//! Returns pointer to a mesh buffer which fits a material 1668//! Returns pointer to a mesh buffer which fits a material
1669/** \param material: material to search for 1669/** \param material: material to search for
1670\return Returns the pointer to the mesh buffer or 1670\return Returns the pointer to the mesh buffer or
1671NULL if there is no such mesh buffer. */ 1671NULL if there is no such mesh buffer. */
1672IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(const video::SMaterial &material) const 1672IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(const video::SMaterial &material) const
1673{ 1673{
1674 return MeshIPol->getMeshBuffer(material); 1674 return MeshIPol->getMeshBuffer(material);
1675} 1675}
1676 1676
1677 1677
1678void CAnimatedMeshHalfLife::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) 1678void CAnimatedMeshHalfLife::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
1679{ 1679{
1680 MeshIPol->setMaterialFlag ( flag, newvalue ); 1680 MeshIPol->setMaterialFlag ( flag, newvalue );
1681} 1681}
1682 1682
1683 1683
1684//! set user axis aligned bounding box 1684//! set user axis aligned bounding box
1685void CAnimatedMeshHalfLife::setBoundingBox(const core::aabbox3df& box) 1685void CAnimatedMeshHalfLife::setBoundingBox(const core::aabbox3df& box)
1686{ 1686{
1687 MeshIPol->setBoundingBox(box); 1687 MeshIPol->setBoundingBox(box);
1688} 1688}
1689 1689
1690 1690
1691} // end namespace scene 1691} // end namespace scene
1692} // end namespace irr 1692} // end namespace irr
1693 1693
1694#endif // _IRR_COMPILE_WITH_MD3_LOADER_ 1694#endif // _IRR_COMPILE_WITH_MD3_LOADER_
1695 1695