Ejemplo n.º 1
0
    xml::Node ModelDefinition::xml(PharmMLWriter &writer) {
        xml::Node mdef("ModelDefinition");
        mdef.setAttribute("xmlns", "http://www.pharmml.org/pharmml/0.8/ModelDefinition");
        // FIXME: Have namespace getter in PharmMLWriter

        for (const auto &vmod : this->VariabilityModels) {
            mdef.addChild(vmod->xml(writer));
        }

        if (this->covariateModel) {
            mdef.addChild(this->covariateModel->xml(writer));
        }

        if (this->parameterModel) {
            mdef.addChild(this->parameterModel->xml(writer));
        }

        if (this->structuralModel) {
            mdef.addChild(this->structuralModel->xml(writer));
        }

        return mdef;
    }
Ejemplo n.º 2
0
// Load: read and return a new CModelDef initialised with data from given file
CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name)
{
	CFileUnpacker unpacker;

	// read everything in from file
	unpacker.Read(filename,"PSMD");
			
	// check version
	if (unpacker.GetVersion()<FILE_READ_VERSION) {
		throw PSERROR_File_InvalidVersion();
	}

	std::auto_ptr<CModelDef> mdef (new CModelDef());
	mdef->m_Name = name;

	// now unpack everything 
	mdef->m_NumVertices = unpacker.UnpackSize();
	mdef->m_pVertices=new SModelVertex[mdef->m_NumVertices];
	unpacker.UnpackRaw(mdef->m_pVertices,sizeof(SModelVertex)*mdef->m_NumVertices);
	
	mdef->m_NumFaces = unpacker.UnpackSize();
	mdef->m_pFaces=new SModelFace[mdef->m_NumFaces];
	unpacker.UnpackRaw(mdef->m_pFaces,sizeof(SModelFace)*mdef->m_NumFaces);
	
	mdef->m_NumBones = unpacker.UnpackSize();
	if (mdef->m_NumBones)
	{
		mdef->m_Bones=new CBoneState[mdef->m_NumBones];
		unpacker.UnpackRaw(mdef->m_Bones,mdef->m_NumBones*sizeof(CBoneState));

		mdef->m_pBlendIndices = new size_t[mdef->m_NumVertices];
		std::vector<SVertexBlend> blends;
		for (size_t i = 0; i < mdef->m_NumVertices; i++)
		{
			const SVertexBlend &blend = mdef->m_pVertices[i].m_Blend;
			if (blend.m_Bone[1] == 0xFF)
			{
				mdef->m_pBlendIndices[i] = blend.m_Bone[0];
			}
			else
			{
				// If there's already a vertex using the same blend as this, then
				// reuse its entry from blends; otherwise add the new one to blends
				size_t j;
				for (j = 0; j < blends.size(); j++)
				{
					if (blend == blends[j]) break;
				}
				if (j >= blends.size())
					blends.push_back(blend);
				mdef->m_pBlendIndices[i] = mdef->m_NumBones + j;
			}
		}

		mdef->m_NumBlends = blends.size();
		mdef->m_pBlends = new SVertexBlend[mdef->m_NumBlends];
		std::copy(blends.begin(), blends.end(), mdef->m_pBlends);
	}

	if (unpacker.GetVersion() >= 2)
	{
		// versions >=2 also have prop point data
		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));

				// build prop point transform
				mdef->m_PropPoints[i].m_Transform.SetIdentity();
				mdef->m_PropPoints[i].m_Transform.Rotate(mdef->m_PropPoints[i].m_Rotation);
				mdef->m_PropPoints[i].m_Transform.Translate(mdef->m_PropPoints[i].m_Position);
			}
		}
	}

	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
		// isn't useful when you want to do correct skinning, so later versions
		// store them in world space. So, fix the old models by skinning each
		// vertex:

		if (mdef->m_NumBones) // only do skinned models
		{
			std::vector<CMatrix3D> bindPose (mdef->m_NumBones);

			for (size_t i = 0; i < mdef->m_NumBones; ++i)
			{
				bindPose[i].SetIdentity();
				bindPose[i].Rotate(mdef->m_Bones[i].m_Rotation);
				bindPose[i].Translate(mdef->m_Bones[i].m_Translation);
			}

			for (size_t i = 0; i < mdef->m_NumVertices; ++i)
			{
				mdef->m_pVertices[i].m_Coords = SkinPoint(mdef->m_pVertices[i], &bindPose[0]);
				mdef->m_pVertices[i].m_Norm = SkinNormal(mdef->m_pVertices[i], &bindPose[0]);
			}
		}
	}

	return mdef.release();
}