Ticket #2026: skinning.patch
File skinning.patch, 29.3 KB (added by , 11 years ago) |
---|
-
source/graphics/Model.cpp
173 173 ValidatePosition(); 174 174 175 175 // extend bounds by vertex positions at the frame 176 CVector3D tempRes; 176 177 for (size_t i=0;i<numverts;i++) 177 178 { 178 result += CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices()); 179 CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices(), tempRes); 180 result += tempRes; 179 181 } 180 182 // advance to next frame 181 183 m_AnimTime += anim->GetFrameTime(); … … 190 192 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 191 193 const CBoundingBoxAligned CModel::GetWorldBoundsRec() 192 194 { 193 CBoundingBoxAligned bounds = GetWorldBounds(); 194 for (size_t i = 0; i < m_Props.size(); ++i) 195 CBoundingBoxAligned bounds (GetWorldBounds()); 196 const size_t propSize = m_Props.size(); 197 for (size_t i = 0; i < propSize; i++) 195 198 bounds += m_Props[i].m_Model->GetWorldBoundsRec(); 196 199 return bounds; 197 200 } … … 201 204 CBoundingBoxAligned objBounds = GetObjectBounds(); // updates the (children-not-included) object-space bounds if necessary 202 205 203 206 // now extend these bounds to include the props' selection bounds (if any) 204 for (size_t i = 0; i < m_Props.size(); ++i) 207 const size_t propSize = m_Props.size(); 208 for (size_t i = 0; i < propSize; ++i) 205 209 { 206 210 const Prop& prop = m_Props[i]; 207 211 if (prop.m_Hidden) … … 325 329 ENSURE(m_PositionValid); 326 330 return; 327 331 } 328 329 if (m_Anim && m_BoneMatrices)330 {331 // PROFILE( "generating bone matrices" );332 332 333 ENSURE(m_pModelDef->GetNumBones() == m_Anim->m_AnimDef->GetNumKeys()); 334 335 m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime, m_BoneMatrices, !(m_Flags & MODELFLAG_NOLOOPANIMATION)); 336 } 337 else if (m_BoneMatrices) 333 const size_t numBones = m_pModelDef->GetNumBones(); 334 const bool hasBones = m_BoneMatrices && numBones != 0; 335 // For CPU skinning, we precompute as much as possible so that the only 336 // per-vertex work is a single matrix*vec multiplication. 337 // For GPU skinning, we try to minimise CPU work by doing most computation 338 // in the vertex shader instead. 339 // Using g_Renderer.m_Options to detect CPU vs GPU is a bit hacky, 340 // and this doesn't allow the setting to change at runtime, but there isn't 341 // an obvious cleaner way to determine what data needs to be computed, 342 // and GPU skinning is a rarely-used experimental feature anyway. 343 const bool worldSpaceBoneMatrices = !g_Renderer.m_Options.m_GPUSkinning; 344 const bool computeBlendMatrices = !g_Renderer.m_Options.m_GPUSkinning; 345 const CMatrix3D transform (GetTransform()); 346 CMatrix3D * const bonesMatrices = m_BoneMatrices; 347 if (hasBones) 338 348 { 339 // Bones but no animation - probably a buggy actor forgot to set up the animation,340 // so just render it in its bind pose341 349 342 for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++)350 if (m_Anim) 343 351 { 344 m_BoneMatrices[i].SetIdentity(); 345 m_BoneMatrices[i].Rotate(m_pModelDef->GetBones()[i].m_Rotation); 346 m_BoneMatrices[i].Translate(m_pModelDef->GetBones()[i].m_Translation); 352 // PROFILE( "generating bone matrices" ); 353 354 ENSURE(numBones == m_Anim->m_AnimDef->GetNumKeys()); 355 356 m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime, bonesMatrices, !(m_Flags & MODELFLAG_NOLOOPANIMATION)); 347 357 } 348 } 358 else 359 { 360 // Bones but no animation - probably a buggy actor forgot to set up the animation, 361 // so just render it in its bind pose 362 const CBoneState * const boneStates = m_pModelDef->GetBones(); 363 for (size_t i = 0; i < numBones; i++) 364 { 365 bonesMatrices[i].SetIdentity(); 366 bonesMatrices[i].Rotate(boneStates[i].m_Rotation); 367 bonesMatrices[i].Translate(boneStates[i].m_Translation); 368 } 369 } 349 370 350 // For CPU skinning, we precompute as much as possible so that the only351 // per-vertex work is a single matrix*vec multiplication.352 // For GPU skinning, we try to minimise CPU work by doing most computation353 // in the vertex shader instead.354 // Using g_Renderer.m_Options to detect CPU vs GPU is a bit hacky,355 // and this doesn't allow the setting to change at runtime, but there isn't356 // an obvious cleaner way to determine what data needs to be computed,357 // and GPU skinning is a rarely-used experimental feature anyway.358 bool worldSpaceBoneMatrices = !g_Renderer.m_Options.m_GPUSkinning;359 bool computeBlendMatrices = !g_Renderer.m_Options.m_GPUSkinning;360 371 361 if (m_BoneMatrices && worldSpaceBoneMatrices) 362 { 363 // add world-space transformation to m_BoneMatrices 364 const CMatrix3D transform = GetTransform(); 365 for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++) 366 m_BoneMatrices[i].Concatenate(transform); 372 373 if (worldSpaceBoneMatrices) 374 { 375 // add world-space transformation to m_BoneMatrices 376 for (size_t i = 0; i < numBones; i++) 377 bonesMatrices[i].Concatenate(transform); 378 } 367 379 } 368 369 380 // our own position is now valid; now we can safely update our props' positions without fearing 370 381 // that doing so will cause a revalidation of this model (see recursion above). 371 382 m_PositionValid = true; … … 375 386 { 376 387 const Prop& prop=m_Props[j]; 377 388 378 CMatrix3D proptransform = prop.m_Point->m_Transform; ;389 CMatrix3D proptransform = prop.m_Point->m_Transform; 379 390 if (prop.m_Point->m_BoneIndex != 0xff) 380 391 { 381 CMatrix3D boneMatrix = m_BoneMatrices[prop.m_Point->m_BoneIndex];392 CMatrix3D boneMatrix (bonesMatrices[prop.m_Point->m_BoneIndex]); 382 393 if (!worldSpaceBoneMatrices) 383 boneMatrix.Concatenate( GetTransform());394 boneMatrix.Concatenate(transform); 384 395 proptransform.Concatenate(boneMatrix); 385 396 } 386 397 else 387 398 { 388 399 // not relative to any bone; just apply world-space transformation (i.e. relative to object-space origin) 389 proptransform.Concatenate( m_Transform);400 proptransform.Concatenate(transform); 390 401 } 391 402 392 403 prop.m_Model->SetTransform(proptransform); 393 404 prop.m_Model->ValidatePosition(); 394 405 } 395 406 396 if ( m_BoneMatrices)407 if (hasBones) 397 408 { 398 for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++) 409 const CMatrix3D * const inverseBoneMatrices = m_pModelDef->GetInverseBindBoneMatrices(); 410 for (size_t i = 0; i < numBones; i++) 399 411 { 400 m_BoneMatrices[i] = m_BoneMatrices[i] * m_pModelDef->GetInverseBindBoneMatrices()[i]; 412 //m_BoneMatrices[i] = m_BoneMatrices[i] * inverseBoneMatrices[i]; 413 bonesMatrices[i].mul(inverseBoneMatrices[i]); 401 414 } 402 403 415 // Note: there is a special case of joint influence, in which the vertex 404 416 // is influenced by the bind-shape transform instead of a particular bone, 405 417 // which we indicate with the blending bone ID set to the total number 406 418 // of bones. But since we're skinning in world space, we use the model's 407 419 // world space transform and store that matrix in this special index. 408 420 // (see http://trac.wildfiregames.com/ticket/1012) 409 m_BoneMatrices[m_pModelDef->GetNumBones()] = m_Transform;421 bonesMatrices[numBones] = m_Transform; 410 422 411 423 if (computeBlendMatrices) 412 m_pModelDef->BlendBoneMatrices( m_BoneMatrices);424 m_pModelDef->BlendBoneMatrices(bonesMatrices); 413 425 } 414 426 } 415 427 -
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 {