mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-27 04:05:04 +00:00
Inline common vector/matrix operations, for performance.
Remove some redundant vector methods. Compute skinning for positions and normals simultaneously. (These changes reduce skinning cost by >50%.) This was SVN commit r8170.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2009 Wildfire Games.
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -89,6 +89,46 @@ CVector3D CModelDef::SkinNormal(const SModelVertex& vtx,
|
||||
return result;
|
||||
}
|
||||
|
||||
void CModelDef::SkinPointsAndNormals(
|
||||
size_t numVertices,
|
||||
const VertexArrayIterator<CVector3D>& Position,
|
||||
const VertexArrayIterator<CVector3D>& Normal,
|
||||
const SModelVertex* vertices,
|
||||
const CMatrix3D newPoseMatrices[],
|
||||
const CMatrix3D inverseBindMatrices[])
|
||||
{
|
||||
for (size_t j = 0; j < numVertices; ++j)
|
||||
{
|
||||
const SModelVertex vtx = vertices[j];
|
||||
|
||||
CVector3D pos(0, 0, 0);
|
||||
CVector3D normal(0, 0, 0);
|
||||
|
||||
for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i)
|
||||
{
|
||||
CVector3D posBindSpace = inverseBindMatrices[vtx.m_Blend.m_Bone[i]].Transform(vtx.m_Coords);
|
||||
CVector3D normBindSpace = inverseBindMatrices[vtx.m_Blend.m_Bone[i]].Rotate(vtx.m_Norm);
|
||||
|
||||
CVector3D posWorldSpace = newPoseMatrices[vtx.m_Blend.m_Bone[i]].Transform(posBindSpace);
|
||||
CVector3D normWorldSpace = newPoseMatrices[vtx.m_Blend.m_Bone[i]].Rotate(normBindSpace);
|
||||
|
||||
pos += posWorldSpace * vtx.m_Blend.m_Weight[i];
|
||||
normal += normWorldSpace * vtx.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
// If there was more than one influence, the result is probably not going
|
||||
// to be of unit length (since it's a weighted sum of several independent
|
||||
// unit vectors), so we need to normalise it.
|
||||
// (It's fairly common to only have one influence, so it seems sensible to
|
||||
// optimise that case a bit.)
|
||||
if (vtx.m_Blend.m_Bone[1] != 0xff) // if more than one influence
|
||||
normal.Normalize();
|
||||
|
||||
Position[j] = pos;
|
||||
Normal[j] = normal;
|
||||
}
|
||||
}
|
||||
|
||||
// CModelDef Constructor
|
||||
CModelDef::CModelDef()
|
||||
: m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), m_NumBones(0), m_Bones(0),
|
||||
|
||||
Reference in New Issue
Block a user