1
1
forked from 0ad/0ad

Add automatic 'root' prop point when loading old PMDs

This was SVN commit r8666.
This commit is contained in:
Ykkrosh 2010-11-20 20:16:06 +00:00
parent eeb9fc2145
commit 1d8972a540
5 changed files with 44 additions and 35 deletions

View File

@ -384,7 +384,7 @@ void CModel::CopyAnimationFrom(CModel* source)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AddProp: add a prop to the model on the given point
void CModel::AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry)
void CModel::AddProp(const SPropPoint* point, CModel* model, CObjectEntry* objectentry)
{
// position model according to prop point position
model->SetTransform(point->m_Transform);
@ -397,7 +397,7 @@ void CModel::AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry
m_Props.push_back(prop);
}
void CModel::AddAmmoProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry)
void CModel::AddAmmoProp(const SPropPoint* point, CModel* model, CObjectEntry* objectentry)
{
AddProp(point, model, objectentry);
m_AmmoPropPoint = point;

View File

@ -51,7 +51,7 @@ public:
{
Prop() : m_Point(0), m_Model(0), m_ObjectEntry(0), m_Hidden(false) {}
SPropPoint* m_Point;
const SPropPoint* m_Point;
CModel* m_Model;
CObjectEntry* m_ObjectEntry;
@ -159,13 +159,13 @@ public:
/**
* Add a prop to the model on the given point.
*/
void AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry);
void AddProp(const SPropPoint* point, CModel* model, CObjectEntry* objectentry);
/**
* Add a prop to the model on the given point, and treat it as the ammo prop.
* The prop will be hidden by default.
*/
void AddAmmoProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry);
void AddAmmoProp(const SPropPoint* point, CModel* model, CObjectEntry* objectentry);
/**
* Show the ammo prop (if any), and hide any other props on that prop point.
@ -237,7 +237,7 @@ private:
/**
* The prop point to which the ammo prop is attached, or NULL if none
*/
SPropPoint* m_AmmoPropPoint;
const SPropPoint* m_AmmoPropPoint;
/**
* If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop

View File

@ -132,7 +132,7 @@ void CModelDef::SkinPointsAndNormals(
// CModelDef Constructor
CModelDef::CModelDef()
: m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), m_NumBones(0), m_Bones(0),
m_NumPropPoints(0), m_PropPoints(0), m_Name(L"[not loaded]")
m_Name(L"[not loaded]")
{
}
@ -144,14 +144,13 @@ CModelDef::~CModelDef()
delete[] m_pVertices;
delete[] m_pFaces;
delete[] m_Bones;
delete[] m_PropPoints;
}
// FindPropPoint: find and return pointer to prop point matching given name;
// return null if no match (case insensitive search)
SPropPoint* CModelDef::FindPropPoint(const char* name) const
const SPropPoint* CModelDef::FindPropPoint(const char* name) const
{
for (size_t i = 0; i < m_NumPropPoints; ++i)
for (size_t i = 0; i < m_PropPoints.size(); ++i)
if (m_PropPoints[i].m_Name == name)
return &m_PropPoints[i];
@ -193,14 +192,16 @@ CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name)
if (unpacker.GetVersion() >= 2)
{
// versions >=2 also have prop point data
mdef->m_NumPropPoints = unpacker.UnpackSize();
if (mdef->m_NumPropPoints) {
mdef->m_PropPoints=new SPropPoint[mdef->m_NumPropPoints];
for (size_t i=0;i<mdef->m_NumPropPoints;i++) {
size_t numPropPoints = unpacker.UnpackSize();
mdef->m_PropPoints.resize(numPropPoints);
if (numPropPoints)
{
for (size_t i = 0; i < numPropPoints; i++)
{
unpacker.UnpackString(mdef->m_PropPoints[i].m_Name);
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Position.X, sizeof(mdef->m_PropPoints[i].m_Position));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X, sizeof(mdef->m_PropPoints[i].m_Rotation));
unpacker.UnpackRaw(&mdef->m_PropPoints[i].m_BoneIndex, sizeof(mdef->m_PropPoints[i].m_BoneIndex));
// build prop point transform
mdef->m_PropPoints[i].m_Transform.SetIdentity();
@ -210,6 +211,18 @@ CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name)
}
}
if (unpacker.GetVersion() <= 2)
{
// Versions <=2 don't include the default 'root' prop point, so add it here
SPropPoint prop;
prop.m_Name = "root";
prop.m_Transform.SetIdentity();
prop.m_BoneIndex = 0xFF;
mdef->m_PropPoints.push_back(prop);
}
if (unpacker.GetVersion() <= 2)
{
// Versions <=2 store the vertexes relative to the bind pose. That
@ -244,31 +257,32 @@ CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name)
}
// Save: write the given CModelDef to the given file
void CModelDef::Save(const VfsPath& filename,const CModelDef* mdef)
void CModelDef::Save(const VfsPath& filename, const CModelDef* mdef)
{
CFilePacker packer(FILE_VERSION, "PSMD");
// pack everything up
const size_t numVertices = mdef->GetNumVertices();
packer.PackSize(numVertices);
packer.PackRaw(mdef->GetVertices(),sizeof(SModelVertex)*numVertices);
packer.PackRaw(mdef->GetVertices(), sizeof(SModelVertex) * numVertices);
const size_t numFaces = mdef->GetNumFaces();
packer.PackSize(numFaces);
packer.PackRaw(mdef->GetFaces(),sizeof(SModelFace)*numFaces);
packer.PackRaw(mdef->GetFaces(), sizeof(SModelFace) * numFaces);
const size_t numBones = mdef->m_NumBones;
packer.PackSize(numBones);
if (numBones)
packer.PackRaw(mdef->m_Bones,sizeof(CBoneState)*numBones);
packer.PackRaw(mdef->m_Bones, sizeof(CBoneState) * numBones);
const size_t numPropPoints = mdef->m_NumPropPoints;
const size_t numPropPoints = mdef->m_PropPoints.size();
packer.PackSize(numPropPoints);
for (size_t i=0;i<mdef->m_NumPropPoints;i++) {
for (size_t i = 0; i < numPropPoints; i++)
{
packer.PackString(mdef->m_PropPoints[i].m_Name);
packer.PackRaw(&mdef->m_PropPoints[i].m_Position.X,sizeof(mdef->m_PropPoints[i].m_Position));
packer.PackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X,sizeof(mdef->m_PropPoints[i].m_Rotation));
packer.PackRaw(&mdef->m_PropPoints[i].m_BoneIndex,sizeof(mdef->m_PropPoints[i].m_BoneIndex));
packer.PackRaw(&mdef->m_PropPoints[i].m_Position.X, sizeof(mdef->m_PropPoints[i].m_Position));
packer.PackRaw(&mdef->m_PropPoints[i].m_Rotation.m_V.X, sizeof(mdef->m_PropPoints[i].m_Rotation));
packer.PackRaw(&mdef->m_PropPoints[i].m_BoneIndex, sizeof(mdef->m_PropPoints[i].m_BoneIndex));
}
// flush everything out to file

View File

@ -135,13 +135,9 @@ public:
size_t GetNumBones() const { return (size_t)m_NumBones; }
CBoneState* GetBones() const { return m_Bones; }
// accessor: get prop data
size_t GetNumPropPoints() const { return m_NumPropPoints; }
SPropPoint* GetPropPoints() const { return m_PropPoints; }
// find and return pointer to prop point matching given name; return
// null if no match (case insensitive search)
SPropPoint* FindPropPoint(const char* name) const;
const SPropPoint* FindPropPoint(const char* name) const;
/**
* Transform the given vertex's position from the bind pose into the new pose.
@ -205,8 +201,7 @@ public:
size_t m_NumBones;
CBoneState* m_Bones;
// prop point data
size_t m_NumPropPoints;
SPropPoint* m_PropPoints;
std::vector<SPropPoint> m_PropPoints;
private:
VfsPath m_Name; // filename

View File

@ -181,7 +181,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
isAmmo = true;
}
SPropPoint* proppoint = modeldef->FindPropPoint(ppn.c_str());
const SPropPoint* proppoint = modeldef->FindPropPoint(ppn.c_str());
if (proppoint)
{
CModel* propmodel = oe->m_Model->Clone();