Files
bullet3/Extras/FCollada/FCDocument/FCDPhysicsRigidBodyInstance.cpp
2006-05-25 19:18:29 +00:00

199 lines
6.1 KiB
C++

/*
Copyright (C) 2005-2006 Feeling Software Inc.
MIT License: http://www.opensource.org/licenses/mit-license.php
*/
#include "StdAfx.h"
#include "FCDocument/FCDocument.h"
#include "FCDocument/FCDEntity.h"
#include "FCDocument/FCDPhysicsMaterial.h"
#include "FCDocument/FCDPhysicsModel.h"
#include "FCDocument/FCDPhysicsModelInstance.h"
#include "FCDocument/FCDPhysicsRigidBody.h"
#include "FCDocument/FCDPhysicsRigidBodyInstance.h"
#include "FUtils/FUDaeParser.h"
#include "FUtils/FUDaeWriter.h"
using namespace FUDaeParser;
using namespace FUDaeWriter;
FCDPhysicsRigidBodyInstance::FCDPhysicsRigidBodyInstance(FCDocument* document, FCDEntity* _parent) : FCDEntityInstance(document, NULL)
{
if(_parent->GetType() == FCDEntity::PHYSICS_MODEL)
parent = (FCDPhysicsModel*)_parent;
rigidBody = NULL;
physicsMaterial = NULL;
ownsPhysicsMaterial = false;
SetClassName("FCDPhysicsRigidBodyInstance");
}
FCDPhysicsRigidBodyInstance::~FCDPhysicsRigidBodyInstance()
{
parent = NULL;
rigidBody = NULL;
CLEAR_POINTER_VECTOR(parameters);
if(ownsPhysicsMaterial)
{
SAFE_DELETE(physicsMaterial);
}
else
{
physicsMaterial = NULL;
}
}
void FCDPhysicsRigidBodyInstance::AddParameter(FCDPhysicsParameterGeneric* parameter)
{
parameters.push_back(parameter);
}
// Load the geometry instance from the COLLADA document
FUStatus FCDPhysicsRigidBodyInstance::LoadFromXML(xmlNode* instanceNode)
{
FUStatus status = FCDEntityInstance::LoadFromXML(instanceNode);
if (!status) return status;
// Check for the expected instantiation node type
if (!IsEquivalent(instanceNode->name, DAE_INSTANCE_RIGID_BODY_ELEMENT))
{
return status.Fail(FS("Unknown element for instantiation of entity: ") + TO_FSTRING(entity->GetDaeId()), instanceNode->line);
}
if (parent == NULL)
{
return status.Fail(FS("No Physics Model parent for rigid body instantiation"), instanceNode->line);
}
string targetNodeId = ReadNodeProperty(instanceNode, DAE_TARGET_ATTRIBUTE);
targetNode = GetDocument()->FindSceneNode(SkipPound(targetNodeId));
if(!targetNode)
{
return status.Fail(FS("Couldn't find target node for instantiation of rigid body"), instanceNode->line);
}
string physicsRigidBodySid = ReadNodeProperty(instanceNode, DAE_BODY_ATTRIBUTE);
entity = rigidBody = parent->FindRigidBodyFromSid(physicsRigidBodySid);
if(!rigidBody)
{
return status.Fail(FS("Couldn't find rigid body for instantiation"), instanceNode->line);
}
//Read in the same children as rigid_body + velocity and angular_velocity
xmlNode* techniqueNode = FindChildByType(instanceNode, DAE_TECHNIQUE_COMMON_ELEMENT);
xmlNode* param = FindChildByType(techniqueNode, DAE_DYNAMIC_ELEMENT);
if(param)
{
FCDPhysicsParameter<bool>* p = new FCDPhysicsParameter<bool>(GetDocument(), DAE_DYNAMIC_ELEMENT);
p->SetValue(FUStringConversion::ToBoolean(ReadNodeContentDirect(param)));
AddParameter(p);
}
xmlNode* massFrame;
massFrame = FindChildByType(techniqueNode, DAE_MASS_FRAME_ELEMENT);
if(massFrame)
{
param = FindChildByType(massFrame, DAE_TRANSLATE_ELEMENT);
if(param)
{
FCDPhysicsParameter<FMVector3>* p = new FCDPhysicsParameter<FMVector3>(GetDocument(), DAE_TRANSLATE_ELEMENT);
p->SetValue(FUStringConversion::ToPoint(ReadNodeContentDirect(param)));
AddParameter(p);
}
param = FindChildByType(massFrame, DAE_ROTATE_ELEMENT);
if(param)
{
FCDPhysicsParameter<FMVector3>* p = new FCDPhysicsParameter<FMVector3>(GetDocument(), DAE_ROTATE_ELEMENT);
p->SetValue(FUStringConversion::ToPoint(ReadNodeContentDirect(param)));
AddParameter(p);
}
}
param = FindChildByType(techniqueNode, DAE_INERTIA_ELEMENT);
if(param)
{
FCDPhysicsParameter<FMVector3>* p = new FCDPhysicsParameter<FMVector3>(GetDocument(), DAE_INERTIA_ELEMENT);
p->SetValue(FUStringConversion::ToPoint(ReadNodeContentDirect(param)));
AddParameter(p);
}
param = FindChildByType(techniqueNode, DAE_MASS_ELEMENT);
if(param)
{
FCDPhysicsParameter<float>* p = new FCDPhysicsParameter<float>(GetDocument(), DAE_MASS_ELEMENT);
p->SetValue(FUStringConversion::ToFloat(ReadNodeContentDirect(param)));
AddParameter(p);
}
param = FindChildByType(techniqueNode, DAE_PHYSICS_MATERIAL_ELEMENT);
if(param)
{
if(physicsMaterial && ownsPhysicsMaterial)
SAFE_DELETE(physicsMaterial);
physicsMaterial = new FCDPhysicsMaterial(GetDocument());
physicsMaterial->LoadFromXML(param);
ownsPhysicsMaterial = true;
}
else
{
param = FindChildByType(techniqueNode, DAE_INSTANCE_PHYSICS_MATERIAL_ELEMENT);
if(param)
{
physicsMaterial = GetDocument()->FindPhysicsMaterial(ReadNodeId(param));
ownsPhysicsMaterial = false;
}
}
param = FindChildByType(techniqueNode, DAE_VELOCITY_ELEMENT);
if(param)
{
FCDPhysicsParameter<FMVector3>* p = new FCDPhysicsParameter<FMVector3>(GetDocument(), DAE_VELOCITY_ELEMENT);
p->SetValue(FUStringConversion::ToPoint(ReadNodeContentDirect(param)));
AddParameter(p);
}
param = FindChildByType(techniqueNode, DAE_ANGULAR_VELOCITY_ELEMENT);
if(param)
{
FCDPhysicsParameter<FMVector3>* p = new FCDPhysicsParameter<FMVector3>(GetDocument(), DAE_ANGULAR_VELOCITY_ELEMENT);
p->SetValue(FUStringConversion::ToPoint(ReadNodeContentDirect(param)));
AddParameter(p);
}
return status;
}
FCDPhysicsRigidBody* FCDPhysicsRigidBodyInstance::FlattenRigidBody()
{
FCDPhysicsRigidBody* clone = rigidBody->Clone();
clone->Flatten();
for (FCDPhysicsParameterList::iterator itP = parameters.begin(); itP != parameters.end(); ++itP)
{
FCDPhysicsParameterGeneric* param = clone->FindParameterByReference((*itP)->GetReference());
if(param)
{
(*itP)->Overwrite(param);
}
else
{
clone->CopyParameter(*itP);
}
}
if(physicsMaterial)
clone->SetPhysicsMaterial(physicsMaterial);
return clone;
}
// Write out the instantiation information to the xml node tree
xmlNode* FCDPhysicsRigidBodyInstance::WriteToXML(xmlNode* parentNode) const
{
xmlNode* instanceNode = FCDEntityInstance::WriteToXML(parentNode);
//TODO
return instanceNode;
}