Ticket #2026: skinning_update.patch
File skinning_update.patch, 28.8 KB (added by , 11 years ago) |
---|
-
source/graphics/Model.cpp
175 175 ValidatePosition(); 176 176 177 177 // extend bounds by vertex positions at the frame 178 CVector3D tempRes; 178 179 for (size_t i=0;i<numverts;i++) 179 180 { 180 result += CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices()); 181 CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices(), tempRes); 182 result += tempRes; 181 183 } 182 184 // advance to next frame 183 185 m_AnimTime += anim->GetFrameTime(); … … 192 194 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 193 195 const CBoundingBoxAligned CModel::GetWorldBoundsRec() 194 196 { 195 CBoundingBoxAligned bounds = GetWorldBounds(); 196 for (size_t i = 0; i < m_Props.size(); ++i) 197 CBoundingBoxAligned bounds (GetWorldBounds()); 198 const size_t propSize = m_Props.size(); 199 for (size_t i = 0; i < propSize; i++) 197 200 bounds += m_Props[i].m_Model->GetWorldBoundsRec(); 198 201 return bounds; 199 202 } … … 203 206 CBoundingBoxAligned objBounds = GetObjectBounds(); // updates the (children-not-included) object-space bounds if necessary 204 207 205 208 // now extend these bounds to include the props' selection bounds (if any) 206 for (size_t i = 0; i < m_Props.size(); ++i) 209 const size_t propSize = m_Props.size(); 210 for (size_t i = 0; i < propSize; ++i) 207 211 { 208 212 const Prop& prop = m_Props[i]; 209 213 if (prop.m_Hidden) … … 332 336 ENSURE(m_PositionValid); 333 337 return; 334 338 } 335 336 if (m_Anim && m_BoneMatrices)337 {338 // PROFILE( "generating bone matrices" );339 339 340 ENSURE(m_pModelDef->GetNumBones() == m_Anim->m_AnimDef->GetNumKeys()); 341 342 m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime, m_BoneMatrices, !(m_Flags & MODELFLAG_NOLOOPANIMATION)); 343 } 344 else if (m_BoneMatrices) 340 const size_t numBones = m_pModelDef->GetNumBones(); 341 const bool hasBones = m_BoneMatrices && numBones != 0; 342 // For CPU skinning, we precompute as much as possible so that the only 343 // per-vertex work is a single matrix*vec multiplication. 344 // For GPU skinning, we try to minimise CPU work by doing most computation 345 // in the vertex shader instead. 346 // Using g_Renderer.m_Options to detect CPU vs GPU is a bit hacky, 347 // and this doesn't allow the setting to change at runtime, but there isn't 348 // an obvious cleaner way to determine what data needs to be computed, 349 // and GPU skinning is a rarely-used experimental feature anyway. 350 const bool worldSpaceBoneMatrices = !g_Renderer.m_Options.m_GPUSkinning; 351 const bool computeBlendMatrices = !g_Renderer.m_Options.m_GPUSkinning; 352 const CMatrix3D transform (GetTransform()); 353 CMatrix3D * const bonesMatrices = m_BoneMatrices; 354 if (hasBones) 345 355 { 346 // Bones but no animation - probably a buggy actor forgot to set up the animation,347 // so just render it in its bind pose348 356 349 for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)357 if (m_Anim) 350 358 { 351 m_BoneMatrices[i].SetIdentity(); 352 m_BoneMatrices[i].Rotate(m_pModelDef->GetBones()[i].m_Rotation); 353 m_BoneMatrices[i].Translate(m_pModelDef->GetBones()[i].m_Translation); 359 // PROFILE( "generating bone matrices" ); 360 361 ENSURE(numBones == m_Anim->m_AnimDef->GetNumKeys()); 362 363 m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime, bonesMatrices, !(m_Flags & MODELFLAG_NOLOOPANIMATION)); 354 364 } 355 } 365 else 366 { 367 // Bones but no animation - probably a buggy actor forgot to set up the animation, 368 // so just render it in its bind pose 369 const CBoneState * const boneStates = m_pModelDef->GetBones(); 370 for (size_t i = 0; i < numBones; i++) 371 { 372 bonesMatrices[i].SetIdentity(); 373 bonesMatrices[i].Rotate(boneStates[i].m_Rotation); 374 bonesMatrices[i].Translate(boneStates[i].m_Translation); 375 } 376 } 356 377 357 // For CPU skinning, we precompute as much as possible so that the only358 // per-vertex work is a single matrix*vec multiplication.359 // For GPU skinning, we try to minimise CPU work by doing most computation360 // in the vertex shader instead.361 // Using g_Renderer.m_Options to detect CPU vs GPU is a bit hacky,362 // and this doesn't allow the setting to change at runtime, but there isn't363 // an obvious cleaner way to determine what data needs to be computed,364 // and GPU skinning is a rarely-used experimental feature anyway.365 bool worldSpaceBoneMatrices = !g_Renderer.m_Options.m_GPUSkinning;366 bool computeBlendMatrices = !g_Renderer.m_Options.m_GPUSkinning;367 378 368 if (m_BoneMatrices && worldSpaceBoneMatrices) 369 { 370 // add world-space transformation to m_BoneMatrices 371 const CMatrix3D transform = GetTransform(); 372 for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++) 373 m_BoneMatrices[i].Concatenate(transform); 379 380 if (worldSpaceBoneMatrices) 381 { 382 // add world-space transformation to m_BoneMatrices 383 for (size_t i = 0; i < numBones; i++) 384 bonesMatrices[i].Concatenate(transform); 385 } 374 386 } 375 376 387 // our own position is now valid; now we can safely update our props' positions without fearing 377 388 // that doing so will cause a revalidation of this model (see recursion above). 378 389 m_PositionValid = true; … … 386 397 387 398 if (prop.m_Point->m_BoneIndex != 0xff) 388 399 { 389 CMatrix3D boneMatrix = m_BoneMatrices[prop.m_Point->m_BoneIndex];400 CMatrix3D boneMatrix = (bonesMatrices[prop.m_Point->m_BoneIndex]); 390 401 if (!worldSpaceBoneMatrices) 391 boneMatrix.Concatenate( GetTransform());402 boneMatrix.Concatenate(transform); 392 403 proptransform.Concatenate(boneMatrix); 393 404 } 394 405 else … … 420 431 prop.m_Model->ValidatePosition(); 421 432 } 422 433 423 if ( m_BoneMatrices)434 if (hasBones) 424 435 { 425 for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++) 436 const CMatrix3D * const inverseBoneMatrices = m_pModelDef->GetInverseBindBoneMatrices(); 437 for (size_t i = 0; i < numBones; i++) 426 438 { 427 m_BoneMatrices[i] = m_BoneMatrices[i] * m_pModelDef->GetInverseBindBoneMatrices()[i];439 bonesMatrices[i].mul(inverseBoneMatrices[i]); 428 440 } 429 441 430 442 // Note: there is a special case of joint influence, in which the vertex … … 433 445 // of bones. But since we're skinning in world space, we use the model's 434 446 // world space transform and store that matrix in this special index. 435 447 // (see http://trac.wildfiregames.com/ticket/1012) 436 m_BoneMatrices[m_pModelDef->GetNumBones()] = m_Transform;448 bonesMatrices[numBones] = m_Transform; 437 449 438 450 if (computeBlendMatrices) 439 m_pModelDef->BlendBoneMatrices( m_BoneMatrices);451 m_pModelDef->BlendBoneMatrices(bonesMatrices); 440 452 } 441 453 } 442 454 -
source/graphics/ModelDef.cpp
31 31 #endif 32 32 33 33 CVector3D CModelDef::SkinPoint(const SModelVertex& vtx, 34 const CMatrix3D newPoseMatrices[]) 34 const CMatrix3D newPoseMatrices[], 35 CVector3D &result) 35 36 { 36 CVector3D result (0, 0, 0); 37 const uint8_t * const blendBones = vtx.m_Blend.m_Bone; 38 const float * const blendWeight = vtx.m_Blend.m_Weight; 39 const CVector3D &coords = vtx.m_Coords; 40 41 if (blendWeight[0] != 0.0 && blendBones[0] != 0xff) 42 result.mulStore(newPoseMatrices[blendBones[0]].Transform(coords), blendWeight[0]); 43 if (blendWeight[1] != 0.0 && blendBones[1] != 0xff) 44 result.mulAdd(newPoseMatrices[blendBones[1]].Transform(coords), blendWeight[1]); 45 if (blendWeight[2] != 0.0 && blendBones[2] != 0xff) 46 result.mulAdd(newPoseMatrices[blendBones[2]].Transform(coords), blendWeight[2]); 47 if (blendWeight[3] != 0.0 && blendBones[3] != 0xff) 48 result.mulAdd(newPoseMatrices[blendBones[3]].Transform(coords), blendWeight[3]); 37 49 38 for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i) 50 /* 51 result *= 0; 52 for (int i = 0; i < SVertexBlend::SIZE && blendBones[i] != 0xff; i++) 39 53 { 40 result += newPoseMatrices[vtx.m_Blend.m_Bone[i]].Transform(vtx.m_Coords) * vtx.m_Blend.m_Weight[i];41 }42 54 if (blendWeight[i] != 0.0) 55 result.mulAdd(newPoseMatrices[blendBones[i]].Transform(coords), blendWeight[i]); 56 }*/ 43 57 return result; 44 58 } 45 59 46 60 CVector3D CModelDef::SkinNormal(const SModelVertex& vtx, 47 const CMatrix3D newPoseMatrices[]) 61 const CMatrix3D newPoseMatrices[], 62 CVector3D& result) 48 63 { 49 64 // To be correct, the normal vectors apparently need to be multiplied by the 50 65 // inverse of the transpose. Unfortunately inverses are slow. … … 69 84 // (This isn't very good as a proof, but it's better than assuming M is 70 85 // orthogonal when it's clearly not.) 71 86 72 CVector3D result (0, 0, 0); 87 const uint8_t * const blendBones = vtx.m_Blend.m_Bone; 88 const float * const blendWeight = vtx.m_Blend.m_Weight; 89 const CVector3D &normal = vtx.m_Norm; 90 result *= 0; 91 if (blendWeight[0] != 0.0 && blendBones[0] != 0xff) 92 result.mulStore(newPoseMatrices[blendBones[0]].Rotate(normal), blendWeight[0]); 93 if (blendWeight[1] != 0.0 && blendBones[1] != 0xff) 94 result.mulAdd(newPoseMatrices[blendBones[1]].Rotate(normal), blendWeight[1]); 95 if (blendWeight[2] != 0.0 && blendBones[2] != 0xff) 96 result.mulAdd(newPoseMatrices[blendBones[2]].Rotate(normal), blendWeight[2]); 97 if (blendWeight[3] != 0.0 && blendBones[3] != 0xff) 98 result.mulAdd(newPoseMatrices[blendBones[3]].Rotate(normal), blendWeight[3]); 99 /* 100 result *= 0; 101 for (int i = 0; i < SVertexBlend::SIZE && blendBones[i] != 0xff; i++) 102 { 103 if (blendWeight[i] != 0.0f) 104 result.mulAdd(newPoseMatrices[blendBones[i]].Rotate(normal), blendWeight[i]); 105 }*/ 73 106 74 for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i) 75 { 76 result += newPoseMatrices[vtx.m_Blend.m_Bone[i]].Rotate(vtx.m_Norm) * vtx.m_Blend.m_Weight[i]; 77 } 78 107 79 108 // If there was more than one influence, the result is probably not going 80 109 // to be of unit length (since it's a weighted sum of several independent 81 110 // unit vectors), so we need to normalise it. 82 111 // (It's fairly common to only have one influence, so it seems sensible to 83 112 // optimise that case a bit.) 84 if ( vtx.m_Blend.m_Bone[1] != 0xff) // if more than one influence113 if (blendBones[1] != 0xff) // if more than one influence 85 114 result.Normalize(); 86 115 87 116 return result; … … 88 117 } 89 118 90 119 void CModelDef::SkinPointsAndNormals( 91 size_t numVertices,120 const size_t numVertices, 92 121 const VertexArrayIterator<CVector3D>& Position, 93 122 const VertexArrayIterator<CVector3D>& Normal, 94 const SModelVertex* vertices,95 const size_t *blendIndices,123 const SModelVertex* const vertices, 124 const size_t * const blendIndices, 96 125 const CMatrix3D newPoseMatrices[]) 97 126 { 98 127 // To avoid some performance overhead, get the raw vertex array pointers 99 char* PositionData = Position.GetData();100 size_t PositionStride = Position.GetStride();101 char* NormalData = Normal.GetData();102 size_t NormalStride = Normal.GetStride();128 char* const PositionData = Position.GetData(); 129 const size_t PositionStride = Position.GetStride(); 130 char* const NormalData = Normal.GetData(); 131 const size_t NormalStride = Normal.GetStride(); 103 132 104 for (size_t j = 0; j < numVertices; ++j)133 for (size_t j = 0; j < numVertices; j++) 105 134 { 106 135 const SModelVertex& vtx = vertices[j]; 107 136 108 CVector3D pos = newPoseMatrices[blendIndices[j]].Transform(vtx.m_Coords);109 CVector3D norm = newPoseMatrices[blendIndices[j]].Rotate(vtx.m_Norm);137 CVector3D pos (newPoseMatrices[blendIndices[j]].Transform(vtx.m_Coords)); 138 CVector3D norm (newPoseMatrices[blendIndices[j]].Rotate(vtx.m_Norm)); 110 139 111 140 // If there was more than one influence, the result is probably not going 112 141 // to be of unit length (since it's a weighted sum of several independent … … 123 152 124 153 #if ARCH_X86_X64 125 154 void CModelDef::SkinPointsAndNormals_SSE( 126 size_t numVertices,155 const size_t numVertices, 127 156 const VertexArrayIterator<CVector3D>& Position, 128 157 const VertexArrayIterator<CVector3D>& Normal, 129 158 const SModelVertex* vertices, 130 const size_t *blendIndices,159 const size_t * const blendIndices, 131 160 const CMatrix3D newPoseMatrices[]) 132 161 { 133 162 // To avoid some performance overhead, get the raw vertex array pointers 134 163 char* PositionData = Position.GetData(); 135 size_t PositionStride = Position.GetStride();164 const size_t PositionStride = Position.GetStride(); 136 165 char* NormalData = Normal.GetData(); 137 size_t NormalStride = Normal.GetStride();166 const size_t NormalStride = Normal.GetStride(); 138 167 139 168 // Must be aligned correctly for SSE 140 169 ASSERT((intptr_t)newPoseMatrices % 16 == 0); … … 206 235 void CModelDef::BlendBoneMatrices( 207 236 CMatrix3D boneMatrices[]) 208 237 { 238 209 239 for (size_t i = 0; i < m_NumBlends; ++i) 210 240 { 211 241 const SVertexBlend& blend = m_pBlends[i]; 212 242 CMatrix3D& boneMatrix = boneMatrices[m_NumBones + 1 + i]; 243 const uint8_t * const blendBones = blend.m_Bone; 244 const float * const blendWeight = blend.m_Weight; 213 245 214 246 // Note: there is a special case of joint influence, in which the vertex 215 247 // is influenced by the bind-shape matrix instead of a particular bone, … … 218 250 // set up this matrix in boneMatrices. 219 251 // (see http://trac.wildfiregames.com/ticket/1012) 220 252 221 boneMatrix.Blend(boneMatrices[blend.m_Bone[0]], blend.m_Weight[0]); 222 for (size_t j = 1; j < SVertexBlend::SIZE && blend.m_Bone[j] != 0xFF; ++j) 223 boneMatrix.AddBlend(boneMatrices[blend.m_Bone[j]], blend.m_Weight[j]); 253 boneMatrix.Blend(boneMatrices[blendBones[0]], blendWeight[0]); 254 /* 255 for (size_t j = 1; j < SVertexBlend::SIZE && blendBones[j] != 0xFF; ++j) 256 { 257 if (blendWeight[j] != 0.0) 258 boneMatrix.AddBlend(boneMatrices[blendBones[j]], blendWeight[j]); 259 }*/ 260 if (blendWeight[1] != 0.0 && blendBones[1] != 0xff) 261 boneMatrix.AddBlend(boneMatrices[blendBones[1]], blendWeight[1]); 262 if (blendWeight[2] != 0.0 && blendBones[2] != 0xff) 263 boneMatrix.AddBlend(boneMatrices[blendBones[2]], blendWeight[2]); 264 if (blendWeight[3] != 0.0 && blendBones[3] != 0xff) 265 boneMatrix.AddBlend(boneMatrices[blendBones[3]], blendWeight[3]); 224 266 } 225 267 } 226 268 … … 400 442 401 443 for (size_t i = 0; i < mdef->m_NumVertices; ++i) 402 444 { 403 mdef->m_pVertices[i].m_Coords = SkinPoint(mdef->m_pVertices[i], &bindPose[0] );404 mdef->m_pVertices[i].m_Norm = SkinNormal(mdef->m_pVertices[i], &bindPose[0]);445 mdef->m_pVertices[i].m_Coords = SkinPoint(mdef->m_pVertices[i], &bindPose[0], mdef->m_pVertices[i].m_Coords); 446 SkinNormal(mdef->m_pVertices[i], &bindPose[0], mdef->m_pVertices[i].m_Norm); 405 447 } 406 448 } 407 449 } -
source/graphics/ModelDef.h
84 84 // with multiple bones 85 85 struct SVertexBlend 86 86 { 87 enum { SIZE = 4 }; 87 enum { SIZE = 4 }; // WARNING ANY MODIFICATION TO SIZE NEED to add/change loop unroll in SKinPoint/SkinNormal/BlendBonesMatrices 88 88 // index of the influencing bone, or 0xff if none 89 89 u8 m_Bone[SIZE]; 90 90 // weight of the influence; all weights sum to 1 … … 193 193 * @return new world-space vertex coordinates 194 194 */ 195 195 static CVector3D SkinPoint(const SModelVertex& vtx, 196 const CMatrix3D newPoseMatrices[]); 196 const CMatrix3D newPoseMatrices[], 197 CVector3D &result); 197 198 198 199 /** 199 200 * Transform the given vertex's normal from the bind pose into the new pose. … … 201 202 * @return new world-space vertex normal 202 203 */ 203 204 static CVector3D SkinNormal(const SModelVertex& vtx, 204 const CMatrix3D newPoseMatrices[]); 205 const CMatrix3D newPoseMatrices[], 206 CVector3D &result); 205 207 206 208 /** 207 209 * Transform vertices' positions and normals. … … 209 211 * but slightly more efficient.) 210 212 */ 211 213 static void SkinPointsAndNormals( 212 size_t numVertices,214 const size_t numVertices, 213 215 const VertexArrayIterator<CVector3D>& Position, 214 216 const VertexArrayIterator<CVector3D>& Normal, 215 217 const SModelVertex* vertices, 216 const size_t* blendIndices,218 const size_t* const blendIndices, 217 219 const CMatrix3D newPoseMatrices[]); 218 220 219 221 #if ARCH_X86_X64 … … 221 223 * SSE-optimised version of SkinPointsAndNormals. 222 224 */ 223 225 static void SkinPointsAndNormals_SSE( 224 size_t numVertices,226 const size_t numVertices, 225 227 const VertexArrayIterator<CVector3D>& Position, 226 228 const VertexArrayIterator<CVector3D>& Normal, 227 229 const SModelVertex* vertices, 228 const size_t* blendIndices,230 const size_t* const blendIndices, 229 231 const CMatrix3D newPoseMatrices[]); 230 232 #endif 231 233 -
source/maths/Matrix3D.cpp
58 58 //The following clear the matrix and set the 59 59 //rotation of each of the 3 axes 60 60 61 void CMatrix3D::SetXRotation ( float angle)61 void CMatrix3D::SetXRotation (const float angle) 62 62 { 63 63 const float Cos = cosf (angle); 64 64 const float Sin = sinf (angle); … … 69 69 _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; 70 70 } 71 71 72 void CMatrix3D::SetYRotation ( float angle)72 void CMatrix3D::SetYRotation (const float angle) 73 73 { 74 74 const float Cos = cosf (angle); 75 75 const float Sin = sinf (angle); … … 80 80 _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; 81 81 } 82 82 83 void CMatrix3D::SetZRotation ( float angle)83 void CMatrix3D::SetZRotation (const float angle) 84 84 { 85 85 const float Cos = cosf (angle); 86 86 const float Sin = sinf (angle); … … 94 94 //The following apply a rotation to the matrix 95 95 //about each of the axes; 96 96 97 void CMatrix3D::RotateX ( float angle)97 void CMatrix3D::RotateX (const float angle) 98 98 { 99 99 const float Cos = cosf (angle); 100 100 const float Sin = sinf (angle); … … 114 114 _34 = Sin * tmp_24 + Cos * _34; 115 115 } 116 116 117 void CMatrix3D::RotateY ( float angle)117 void CMatrix3D::RotateY (const float angle) 118 118 { 119 119 const float Cos = cosf (angle); 120 120 const float Sin = sinf (angle); … … 134 134 _34 = -Sin * tmp_14 + Cos * _34; 135 135 } 136 136 137 void CMatrix3D::RotateZ ( float angle)137 void CMatrix3D::RotateZ (const float angle) 138 138 { 139 139 const float Cos = cosf (angle); 140 140 const float Sin = sinf (angle); … … 155 155 } 156 156 157 157 //Sets the translation of the matrix 158 void CMatrix3D::SetTranslation ( float x, float y,float z)158 void CMatrix3D::SetTranslation (const float x, const float y, const float z) 159 159 { 160 160 _11=1.0f; _12=0.0f; _13=0.0f; _14=x; 161 161 _21=0.0f; _22=1.0f; _23=0.0f; _24=y; … … 169 169 } 170 170 171 171 //Applies a translation to the matrix 172 void CMatrix3D::Translate( float x, float y,float z)172 void CMatrix3D::Translate(const float x, const float y, const float z) 173 173 { 174 174 _14 += x; 175 175 _24 += y; … … 183 183 _34 += vector.Z; 184 184 } 185 185 186 void CMatrix3D::PostTranslate( float x, float y,float z)186 void CMatrix3D::PostTranslate(const float x, const float y, const float z) 187 187 { 188 188 // Equivalent to "m.SetTranslation(x, y, z); *this = *this * m;" 189 189 _14 += _11*x + _12*y + _13*z; … … 198 198 } 199 199 200 200 //Clears and sets the scaling of the matrix 201 void CMatrix3D::SetScaling ( float x_scale, float y_scale,float z_scale)201 void CMatrix3D::SetScaling (const float x_scale, const float y_scale, const float z_scale) 202 202 { 203 203 _11=x_scale; _12=0.0f; _13=0.0f; _14=0.0f; 204 204 _21=0.0f; _22=y_scale; _23=0.0f; _24=0.0f; … … 207 207 } 208 208 209 209 //Scales the matrix 210 void CMatrix3D::Scale ( float x_scale, float y_scale,float z_scale)210 void CMatrix3D::Scale (const float x_scale, const float y_scale, const float z_scale) 211 211 { 212 212 _11 *= x_scale; 213 213 _12 *= x_scale; -
source/maths/Matrix3D.h
98 98 } 99 99 100 100 // matrix multiplication 101 CMatrix3D operator*(const CMatrix3D &matrix) const101 CMatrix3D operator*(const CMatrix3D& matrix) const 102 102 { 103 103 return CMatrix3D( 104 104 _11*matrix._11 + _12*matrix._21 + _13*matrix._31 + _14*matrix._41, … … 124 124 } 125 125 126 126 // matrix multiplication/assignment 127 CMatrix3D& operator*=(const CMatrix3D &matrix)127 CMatrix3D& operator*=(const CMatrix3D& matrix) 128 128 { 129 129 Concatenate(matrix); 130 130 return *this; … … 142 142 } 143 143 144 144 // matrix addition 145 CMatrix3D operator+(const CMatrix3D &m) const145 CMatrix3D operator+(const CMatrix3D& m) const 146 146 { 147 147 return CMatrix3D( 148 148 _11+m._11, _12+m._12, _13+m._13, _14+m._14, … … 153 153 } 154 154 155 155 // matrix addition/assignment 156 CMatrix3D& operator+=(const CMatrix3D &m)156 CMatrix3D& operator+=(const CMatrix3D& m) 157 157 { 158 158 _11 += m._11; _21 += m._21; _31 += m._31; _41 += m._41; 159 159 _12 += m._12; _22 += m._22; _32 += m._32; _42 += m._42; … … 163 163 } 164 164 165 165 // equality 166 bool operator==(const CMatrix3D &m) const166 bool operator==(const CMatrix3D& m) const 167 167 { 168 168 return _11 == m._11 && _21 == m._21 && _31 == m._31 && _41 == m._41 && 169 169 _12 == m._12 && _22 == m._22 && _32 == m._32 && _42 == m._42 && … … 187 187 // concatenate arbitrary matrix onto this matrix 188 188 void Concatenate(const CMatrix3D& m) 189 189 { 190 (*this) = m * (*this); 190 //(*this) = m * (*this); 191 premul(m); 191 192 } 193 // mul and add wihtout stack alloc 194 void mulAdd(const CMatrix3D& matrixA, const CMatrix3D& matrixB) 195 { 196 _11 += matrixA._11*matrixB._11 +matrixA._12*matrixB._21 +matrixA._13*matrixB._31 +matrixA._14*matrixB._41; 197 _12 += matrixA._11*matrixB._12 +matrixA._12*matrixB._22 +matrixA._13*matrixB._32 +matrixA._14*matrixB._42; 198 _13 += matrixA._11*matrixB._13 +matrixA._12*matrixB._23 +matrixA._13*matrixB._33 +matrixA._14*matrixB._43; 199 _14 += matrixA._11*matrixB._14 +matrixA._12*matrixB._24 +matrixA._13*matrixB._34 +matrixA._14*matrixB._44; 200 201 _21 += matrixA._21*matrixB._11 +matrixA._22*matrixB._21 +matrixA._23*matrixB._31 +matrixA._24*matrixB._41; 202 _22 += matrixA._21*matrixB._12 +matrixA._22*matrixB._22 +matrixA._23*matrixB._32 +matrixA._24*matrixB._42; 203 _23 += matrixA._21*matrixB._13 +matrixA._22*matrixB._23 +matrixA._23*matrixB._33 +matrixA._24*matrixB._43; 204 _24 += matrixA._21*matrixB._14 +matrixA._22*matrixB._24 +matrixA._23*matrixB._34 +matrixA._24*matrixB._44; 205 206 _31 += matrixA._31*matrixB._11 +matrixA._32*matrixB._21 +matrixA._33*matrixB._31 +matrixA._34*matrixB._41; 207 _32 += matrixA._31*matrixB._12 +matrixA._32*matrixB._22 +matrixA._33*matrixB._32 +matrixA._34*matrixB._42; 208 _33 += matrixA._31*matrixB._13 +matrixA._32*matrixB._23 +matrixA._33*matrixB._33 +matrixA._34*matrixB._43; 209 _34 += matrixA._31*matrixB._14 +matrixA._32*matrixB._24 +matrixA._33*matrixB._34 +matrixA._34*matrixB._44; 210 211 _41 += matrixA._41*matrixB._11 +matrixA._42*matrixB._21 +matrixA._43*matrixB._31 +matrixA._44*matrixB._41; 212 _42 += matrixA._41*matrixB._12 +matrixA._42*matrixB._22 +matrixA._43*matrixB._32 +matrixA._44*matrixB._42; 213 _43 += matrixA._41*matrixB._13 +matrixA._42*matrixB._23 +matrixA._43*matrixB._33 +matrixA._44*matrixB._43; 214 _44 += matrixA._41*matrixB._14 +matrixA._42*matrixB._24 +matrixA._43*matrixB._34 +matrixA._44*matrixB._44; 215 216 } 217 // mul and and store wihtout stack alloc 218 void mul(const CMatrix3D& matrixA, const CMatrix3D& matrixB) 219 { 220 _11 = matrixA._11*matrixB._11 +matrixA._12*matrixB._21 +matrixA._13*matrixB._31 +matrixA._14*matrixB._41; 221 _12 = matrixA._11*matrixB._12 +matrixA._12*matrixB._22 +matrixA._13*matrixB._32 +matrixA._14*matrixB._42; 222 _13 = matrixA._11*matrixB._13 +matrixA._12*matrixB._23 +matrixA._13*matrixB._33 +matrixA._14*matrixB._43; 223 _14 = matrixA._11*matrixB._14 +matrixA._12*matrixB._24 +matrixA._13*matrixB._34 +matrixA._14*matrixB._44; 224 225 _21 = matrixA._21*matrixB._11 +matrixA._22*matrixB._21 +matrixA._23*matrixB._31 +matrixA._24*matrixB._41; 226 _22 = matrixA._21*matrixB._12 +matrixA._22*matrixB._22 +matrixA._23*matrixB._32 +matrixA._24*matrixB._42; 227 _23 = matrixA._21*matrixB._13 +matrixA._22*matrixB._23 +matrixA._23*matrixB._33 +matrixA._24*matrixB._43; 228 _24 = matrixA._21*matrixB._14 +matrixA._22*matrixB._24 +matrixA._23*matrixB._34 +matrixA._24*matrixB._44; 229 230 _31 = matrixA._31*matrixB._11 +matrixA._32*matrixB._21 +matrixA._33*matrixB._31 +matrixA._34*matrixB._41; 231 _32 = matrixA._31*matrixB._12 +matrixA._32*matrixB._22 +matrixA._33*matrixB._32 +matrixA._34*matrixB._42; 232 _33 = matrixA._31*matrixB._13 +matrixA._32*matrixB._23 +matrixA._33*matrixB._33 +matrixA._34*matrixB._43; 233 _34 = matrixA._31*matrixB._14 +matrixA._32*matrixB._24 +matrixA._33*matrixB._34 +matrixA._34*matrixB._44; 234 235 _41 = matrixA._41*matrixB._11 +matrixA._42*matrixB._21 +matrixA._43*matrixB._31 +matrixA._44*matrixB._41; 236 _42 = matrixA._41*matrixB._12 +matrixA._42*matrixB._22 +matrixA._43*matrixB._32 +matrixA._44*matrixB._42; 237 _43 = matrixA._41*matrixB._13 +matrixA._42*matrixB._23 +matrixA._43*matrixB._33 +matrixA._44*matrixB._43; 238 _44 = matrixA._41*matrixB._14 +matrixA._42*matrixB._24 +matrixA._43*matrixB._34 +matrixA._44*matrixB._44; 239 240 } 241 242 // matrix pre multiplication wihtout object alloc. 243 void premul(const CMatrix3D& matrixA) 244 { 245 const float __11 = matrixA._11*_11 + matrixA._12*_21 + matrixA._13*_31 + matrixA._14*_41; 246 const float __12 = matrixA._11*_12 + matrixA._12*_22 + matrixA._13*_32 + matrixA._14*_42; 247 const float __13 = matrixA._11*_13 + matrixA._12*_23 + matrixA._13*_33 + matrixA._14*_43; 248 const float __14 = matrixA._11*_14 + matrixA._12*_24 + matrixA._13*_34 + matrixA._14*_44; 249 250 const float __21 = matrixA._21*_11 + matrixA._22*_21 + matrixA._23*_31 + matrixA._24*_41; 251 const float __22 = matrixA._21*_12 + matrixA._22*_22 + matrixA._23*_32 + matrixA._24*_42; 252 const float __23 = matrixA._21*_13 + matrixA._22*_23 + matrixA._23*_33 + matrixA._24*_43; 253 const float __24 = matrixA._21*_14 + matrixA._22*_24 + matrixA._23*_34 + matrixA._24*_44; 254 255 const float __31 = matrixA._31*_11 + matrixA._32*_21 + matrixA._33*_31 + matrixA._34*_41; 256 const float __32 = matrixA._31*_12 + matrixA._32*_22 + matrixA._33*_32 + matrixA._34*_42; 257 const float __33 = matrixA._31*_13 + matrixA._32*_23 + matrixA._33*_33 + matrixA._34*_43; 258 const float __34 = matrixA._31*_14 + matrixA._32*_24 + matrixA._33*_34 + matrixA._34*_44; 259 260 const float __41 = matrixA._41*_11 + matrixA._42*_21 + matrixA._43*_31 + matrixA._44*_41; 261 const float __42 = matrixA._41*_12 + matrixA._42*_22 + matrixA._43*_32 + matrixA._44*_42; 262 const float __43 = matrixA._41*_13 + matrixA._42*_23 + matrixA._43*_33 + matrixA._44*_43; 263 const float __44 = matrixA._41*_14 + matrixA._42*_24 + matrixA._43*_34 + matrixA._44*_44; 192 264 265 _11 = __11; 266 _21 = __21; 267 _31 = __31; 268 _41 = __41; 269 270 _12 = __12; 271 _22 = __22; 272 _32 = __32; 273 _42 = __42; 274 275 _13 = __13; 276 _23 = __23; 277 _33 = __33; 278 _43 = __43; 279 280 _14 = __14; 281 _24 = __24; 282 _34 = __34; 283 _44 = __44; 284 285 } 286 // matrix multiplication wihtout object alloc. 287 void mul(const CMatrix3D& matrixB) 288 { 289 float __1, __2, __3, __4; 290 291 __1 = _11*matrixB._11 + _12*matrixB._21 + _13*matrixB._31 + _14*matrixB._41; 292 __2 = _11*matrixB._12 + _12*matrixB._22 + _13*matrixB._32 + _14*matrixB._42; 293 __3 = _11*matrixB._13 + _12*matrixB._23 + _13*matrixB._33 + _14*matrixB._43; 294 __4 = _11*matrixB._14 + _12*matrixB._24 + _13*matrixB._34 + _14*matrixB._44; 295 296 _11 = __1; _12 = __2; _13 = __3; _14 = __4; 297 298 __1 = _21*matrixB._11 + _22*matrixB._21 + _23*matrixB._31 + _24*matrixB._41; 299 __2 = _21*matrixB._12 + _22*matrixB._22 + _23*matrixB._32 + _24*matrixB._42; 300 __3 = _21*matrixB._13 + _22*matrixB._23 + _23*matrixB._33 + _24*matrixB._43; 301 __4 = _21*matrixB._14 + _22*matrixB._24 + _23*matrixB._34 + _24*matrixB._44; 302 303 _21 = __1; _22 = __2; _23 = __3; _24 = __4; 304 305 __1 = _31*matrixB._11 + _32*matrixB._21 + _33*matrixB._31 + _34*matrixB._41; 306 __2 = _31*matrixB._12 + _32*matrixB._22 + _33*matrixB._32 + _34*matrixB._42; 307 __3 = _31*matrixB._13 + _32*matrixB._23 + _33*matrixB._33 + _34*matrixB._43; 308 __4 = _31*matrixB._14 + _32*matrixB._24 + _33*matrixB._34 + _34*matrixB._44; 309 310 _31 = __1; _32 = __2; _33 = __3; _34 = __4; 311 312 __1 = _41*matrixB._11 + _42*matrixB._21 + _43*matrixB._31 + _44*matrixB._41; 313 __2 = _41*matrixB._12 + _42*matrixB._22 + _43*matrixB._32 + _44*matrixB._42; 314 __3 = _41*matrixB._13 + _42*matrixB._23 + _43*matrixB._33 + _44*matrixB._43; 315 __4 = _41*matrixB._14 + _42*matrixB._24 + _43*matrixB._34 + _44*matrixB._44; 316 317 _41 = __1; _42 = __2; _43 = __3; _44 = __4; 318 } 193 319 // blend matrix using only 4x3 subset 194 void Blend(const CMatrix3D& m, float f)320 void Blend(const CMatrix3D& m, const float f) 195 321 { 196 322 _11 = m._11*f; _21 = m._21*f; _31 = m._31*f; 197 323 _12 = m._12*f; _22 = m._22*f; _32 = m._32*f; … … 200 326 } 201 327 202 328 // blend matrix using only 4x3 and add onto existing blend 203 void AddBlend(const CMatrix3D& m, float f)329 void AddBlend(const CMatrix3D& m, const float f) 204 330 { 205 331 _11 += m._11*f; _21 += m._21*f; _31 += m._31*f; 206 332 _12 += m._12*f; _22 += m._22*f; _32 += m._32*f; -
source/maths/Vector3D.h
81 81 { 82 82 return CVector3D(X * value, Y * value, Z * value); 83 83 } 84 85 void mulAdd(const CVector3D& vector, const float value) 86 { 87 X += vector.X * value; 88 Y += vector.Y * value; 89 Z += vector.Z * value; 90 } 91 void mulStore(const CVector3D& vector, const float value) 92 { 93 X = vector.X * value; 94 Y = vector.Y * value; 95 Z = vector.Z * value; 96 } 97 void mul(const float value) 98 { 99 X *= value; 100 Y *= value; 101 Z *= value; 102 } 84 103 85 104 CVector3D& operator*=(float value) 86 105 {