Initial commit
This commit is contained in:
702
engines/hpl1/engine/physics/PhysicsJoint.cpp
Normal file
702
engines/hpl1/engine/physics/PhysicsJoint.cpp
Normal file
@@ -0,0 +1,702 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/physics/PhysicsJoint.h"
|
||||
|
||||
#include "hpl1/engine/physics/CollideShape.h"
|
||||
#include "hpl1/engine/physics/PhysicsBody.h"
|
||||
#include "hpl1/engine/physics/PhysicsController.h"
|
||||
#include "hpl1/engine/physics/PhysicsWorld.h"
|
||||
#include "hpl1/engine/system/low_level_system.h"
|
||||
|
||||
#include "hpl1/engine/scene/SoundEntity.h"
|
||||
#include "hpl1/engine/sound/Sound.h"
|
||||
#include "hpl1/engine/sound/SoundChannel.h"
|
||||
#include "hpl1/engine/sound/SoundHandler.h"
|
||||
|
||||
#include "hpl1/engine/scene/Scene.h"
|
||||
#include "hpl1/engine/scene/World3D.h"
|
||||
|
||||
#include "hpl1/engine/game/Game.h"
|
||||
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
|
||||
#include "hpl1/engine/game/ScriptFuncs.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iPhysicsJoint::iPhysicsJoint(const tString &asName, iPhysicsBody *apParentBody, iPhysicsBody *apChildBody,
|
||||
iPhysicsWorld *apWorld, const cVector3f &avPivotPoint)
|
||||
: msName(asName), mpParentBody(apParentBody), mpChildBody(apChildBody), mpWorld(apWorld) {
|
||||
mMaxLimit.msSound = "";
|
||||
mMinLimit.msSound = "";
|
||||
|
||||
if (apParentBody) {
|
||||
apParentBody->AddJoint(this);
|
||||
m_mtxParentBodySetup = apParentBody->GetLocalMatrix();
|
||||
} else {
|
||||
m_mtxParentBodySetup = cMatrixf::Identity;
|
||||
}
|
||||
|
||||
m_mtxPrevChild = cMatrixf::Identity;
|
||||
m_mtxPrevParent = cMatrixf::Identity;
|
||||
|
||||
apChildBody->AddJoint(this);
|
||||
m_mtxChildBodySetup = apChildBody->GetLocalMatrix();
|
||||
|
||||
cMatrixf m_mtxInvChild = cMath::MatrixInverse(apChildBody->GetLocalMatrix());
|
||||
mvLocalPivot = cMath::MatrixMul(m_mtxInvChild, avPivotPoint);
|
||||
mvStartPivotPoint = avPivotPoint;
|
||||
|
||||
msMoveSound = "";
|
||||
|
||||
mbHasCollided = false;
|
||||
mpSound = NULL;
|
||||
|
||||
mpCallback = NULL;
|
||||
|
||||
mbAutoDeleteCallback = false;
|
||||
|
||||
mpUserData = NULL;
|
||||
|
||||
mbBreakable = false;
|
||||
mfBreakForce = 0;
|
||||
msBreakSound = "";
|
||||
mbBroken = false;
|
||||
|
||||
mfStickyMinDistance = 0;
|
||||
mfStickyMaxDistance = 0;
|
||||
|
||||
mlLimitStepCount = 0;
|
||||
|
||||
mlSpeedCount = 0;
|
||||
|
||||
mbLimitAutoSleep = false;
|
||||
mfLimitAutoSleepDist = 0.02f;
|
||||
mlLimitAutoSleepNumSteps = 10;
|
||||
|
||||
// Log("Created joint '%s'\n",msName.c_str());
|
||||
}
|
||||
|
||||
iPhysicsJoint::~iPhysicsJoint() {
|
||||
if (mbAutoDeleteCallback && mpCallback)
|
||||
hplDelete(mpCallback);
|
||||
|
||||
// Destroy all controllers.
|
||||
tPhysicsControllerMapIt it = m_mapControllers.begin();
|
||||
for (; it != m_mapControllers.end(); ++it) {
|
||||
mpWorld->DestroyController(it->second);
|
||||
}
|
||||
|
||||
if (mpChildBody)
|
||||
mpChildBody->RemoveJoint(this);
|
||||
if (mpParentBody)
|
||||
mpParentBody->RemoveJoint(this);
|
||||
|
||||
if (mpSound)
|
||||
mpWorld->GetWorld3D()->DestroySoundEntity(mpSound);
|
||||
|
||||
// Log("Deleted joint '%s'\n",msName.c_str());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This should only be used by PhysicsBody.
|
||||
*/
|
||||
void iPhysicsJoint::RemoveBody(iPhysicsBody *apBody) {
|
||||
if (mpParentBody == apBody)
|
||||
mpParentBody = NULL;
|
||||
if (mpChildBody == apBody)
|
||||
mpChildBody = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::AddController(iPhysicsController *apController) {
|
||||
|
||||
// Add controller top map
|
||||
m_mapControllers.insert(tPhysicsControllerMap::value_type(apController->GetName(), apController));
|
||||
|
||||
// Set properties
|
||||
apController->SetBody(mpChildBody);
|
||||
apController->SetJoint(this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iPhysicsController *iPhysicsJoint::GetController(const tString &asName) {
|
||||
tPhysicsControllerMapIt it = m_mapControllers.find(asName);
|
||||
if (it == m_mapControllers.end())
|
||||
return NULL;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool iPhysicsJoint::ChangeController(const tString &asName) {
|
||||
iPhysicsController *pNewCtrl = GetController(asName);
|
||||
if (pNewCtrl == NULL)
|
||||
return false;
|
||||
|
||||
tPhysicsControllerMapIt it = m_mapControllers.begin();
|
||||
for (; it != m_mapControllers.end(); ++it) {
|
||||
iPhysicsController *pCtrl = it->second;
|
||||
|
||||
if (pCtrl == pNewCtrl) {
|
||||
pCtrl->SetActive(true);
|
||||
} else {
|
||||
pCtrl->SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::SetAllControllersPaused(bool abX) {
|
||||
tPhysicsControllerMapIt it = m_mapControllers.begin();
|
||||
for (; it != m_mapControllers.end(); ++it) {
|
||||
iPhysicsController *pCtrl = it->second;
|
||||
|
||||
pCtrl->SetPaused(abX);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cPhysicsControllerIterator iPhysicsJoint::GetControllerIterator() {
|
||||
return cPhysicsControllerIterator(&m_mapControllers);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PROTECTED METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::OnMaxLimit() {
|
||||
if (mbHasCollided == false && mpCallback) {
|
||||
mpCallback->OnMaxLimit(this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Check if any of the controllers has a OnMax end.
|
||||
if (mbHasCollided == false) {
|
||||
// Log("OnMax!\n");
|
||||
tPhysicsControllerMapIt it = m_mapControllers.begin();
|
||||
for (; it != m_mapControllers.end(); ++it) {
|
||||
iPhysicsController *pCtrl = it->second;
|
||||
|
||||
// Log("Ctrl %s: %d\n",pCtrl->GetName().c_str(),(int)pCtrl->GetEndType());
|
||||
|
||||
if (pCtrl->IsActive() && pCtrl->GetEndType() == ePhysicsControllerEnd_OnMax) {
|
||||
pCtrl->SetActive(false);
|
||||
iPhysicsController *pNextCtrl = GetController(pCtrl->GetNextController());
|
||||
if (pNextCtrl)
|
||||
pNextCtrl->SetActive(true);
|
||||
else
|
||||
Warning("Controller '%s' does not exist in joint '%s'\n", pCtrl->GetNextController().c_str(), msName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LimitEffect(&mMaxLimit);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::OnMinLimit() {
|
||||
if (mbHasCollided == false && mpCallback) {
|
||||
mpCallback->OnMinLimit(this);
|
||||
}
|
||||
//////////////////////////////////////////////////
|
||||
// Check if any of the controllers has a OnMin end.
|
||||
if (mbHasCollided == false) {
|
||||
// Log("OnMin!\n");
|
||||
|
||||
tPhysicsControllerMapIt it = m_mapControllers.begin();
|
||||
for (; it != m_mapControllers.end(); ++it) {
|
||||
iPhysicsController *pCtrl = it->second;
|
||||
|
||||
if (pCtrl->IsActive() && pCtrl->GetEndType() == ePhysicsControllerEnd_OnMin) {
|
||||
pCtrl->SetActive(false);
|
||||
iPhysicsController *pNextCtrl = GetController(pCtrl->GetNextController());
|
||||
if (pNextCtrl)
|
||||
pNextCtrl->SetActive(true);
|
||||
else
|
||||
Warning("Controller '%s' does not exist in joint '%s'\n", pCtrl->GetNextController().c_str(), msName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LimitEffect(&mMinLimit);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::CalcSoundFreq(float afSpeed, float *apFreq, float *apVol) {
|
||||
float fAbsSpeed = ABS(afSpeed);
|
||||
float fFreq = 1;
|
||||
float fVolume = 1;
|
||||
|
||||
// Higher than middle
|
||||
if (fAbsSpeed >= mfMiddleMoveSpeed) {
|
||||
if (fAbsSpeed >= mfMaxMoveFreqSpeed) {
|
||||
fFreq = mfMaxMoveFreq;
|
||||
fVolume = mfMaxMoveVolume;
|
||||
} else {
|
||||
// Calculate how close the speed is to max.
|
||||
float fT = (fAbsSpeed - mfMiddleMoveSpeed) /
|
||||
(mfMaxMoveFreqSpeed - mfMiddleMoveSpeed);
|
||||
|
||||
fFreq = (1 - fT) + fT * mfMaxMoveFreq;
|
||||
fVolume = mfMiddleMoveVolume * (1 - fT) + fT * mfMaxMoveVolume;
|
||||
}
|
||||
}
|
||||
// Below middle
|
||||
else {
|
||||
if (fAbsSpeed <= mfMinMoveFreqSpeed) {
|
||||
fFreq = mfMinMoveFreq;
|
||||
fVolume = mfMinMoveVolume;
|
||||
} else {
|
||||
// Calculate how close the speed is to max.
|
||||
float fT = (mfMiddleMoveSpeed - fAbsSpeed) /
|
||||
(mfMiddleMoveSpeed - mfMinMoveFreqSpeed);
|
||||
|
||||
fFreq = (1 - fT) + fT * mfMinMoveFreq;
|
||||
fVolume = mfMiddleMoveVolume * (1 - fT) + fT * mfMinMoveVolume;
|
||||
}
|
||||
}
|
||||
|
||||
*apFreq = fFreq;
|
||||
*apVol = fVolume;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::OnPhysicsUpdate() {
|
||||
// Get the pivot point, if there is no parent, it is stuck.
|
||||
if (mpParentBody)
|
||||
mvPivotPoint = cMath::MatrixMul(mpChildBody->GetLocalMatrix(), mvLocalPivot);
|
||||
|
||||
cWorld3D *pWorld3D = mpWorld->GetWorld3D();
|
||||
if (pWorld3D == NULL)
|
||||
return;
|
||||
if (msMoveSound == "")
|
||||
return;
|
||||
|
||||
if (mpWorld->GetWorld3D()->GetSound()->GetSoundHandler()->GetSilent())
|
||||
return;
|
||||
|
||||
//////////////////////////////////////
|
||||
// Get the speed
|
||||
cVector3f vVel(0, 0, 0);
|
||||
// Linear
|
||||
if (mMoveSpeedType == ePhysicsJointSpeed_Linear) {
|
||||
if (mpParentBody) {
|
||||
vVel = mpChildBody->GetLinearVelocity() - mpParentBody->GetLinearVelocity();
|
||||
} else {
|
||||
vVel = mpChildBody->GetLinearVelocity();
|
||||
}
|
||||
}
|
||||
// Angular
|
||||
else {
|
||||
if (mpParentBody) {
|
||||
vVel = mpChildBody->GetAngularVelocity() - mpParentBody->GetAngularVelocity();
|
||||
} else {
|
||||
vVel = mpChildBody->GetAngularVelocity();
|
||||
}
|
||||
}
|
||||
|
||||
// Check so the body is not still
|
||||
if (mpParentBody) {
|
||||
if (m_mtxPrevChild == mpChildBody->GetLocalMatrix() &&
|
||||
m_mtxPrevParent == mpParentBody->GetLocalMatrix()) {
|
||||
vVel = 0;
|
||||
}
|
||||
m_mtxPrevChild = mpChildBody->GetLocalMatrix();
|
||||
m_mtxPrevParent = mpParentBody->GetLocalMatrix();
|
||||
} else {
|
||||
if (m_mtxPrevChild == mpChildBody->GetLocalMatrix()) {
|
||||
vVel = 0;
|
||||
}
|
||||
m_mtxPrevChild = mpChildBody->GetLocalMatrix();
|
||||
}
|
||||
|
||||
float fSpeed = vVel.Length();
|
||||
|
||||
if (pWorld3D->SoundEntityExists(mpSound) == false) {
|
||||
mpSound = NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Create and update sound if speed is high enough
|
||||
// Joint has sound
|
||||
if (mpSound) {
|
||||
// Log("Updating %s\n",mpSound->GetName().c_str());
|
||||
float fMin = cMath::Max(mfMinMoveSpeed - 0.2f, 0.1f);
|
||||
if (fSpeed <= fMin) {
|
||||
mpSound->FadeOut(4.3f);
|
||||
mpSound = NULL;
|
||||
} else {
|
||||
// Log("Getting entry!\n");
|
||||
cSoundEntry *pEntry = mpSound->GetSoundEntry(eSoundEntityType_Main);
|
||||
if (pEntry) {
|
||||
// Log("Update entry!\n");
|
||||
float fFreq, fVolume;
|
||||
CalcSoundFreq(fSpeed, &fFreq, &fVolume);
|
||||
|
||||
pEntry->mfNormalSpeed = fFreq;
|
||||
pEntry->mfNormalVolumeMul = fVolume;
|
||||
|
||||
// Log("Speed: %f Vol: %f Freq: %f\n",fSpeed,fVolume,fFreq);
|
||||
} else {
|
||||
// Log("Null entry!\n");
|
||||
}
|
||||
|
||||
mpSound->SetPosition(mvPivotPoint);
|
||||
}
|
||||
}
|
||||
//////////////////////
|
||||
// Joint has no sound
|
||||
else {
|
||||
/////////////////////////////
|
||||
// Speed is over limit
|
||||
if (fSpeed > mfMinMoveSpeed) {
|
||||
if (mlSpeedCount >= 3) {
|
||||
mlSpeedCount = 0;
|
||||
mpSound = pWorld3D->CreateSoundEntity("MoveSound", msMoveSound, true);
|
||||
if (mpSound) {
|
||||
mpSound->SetIsSaved(false);
|
||||
mpSound->FadeIn(3.3f);
|
||||
}
|
||||
// Log("Starting!\n");
|
||||
} else {
|
||||
mlSpeedCount++;
|
||||
}
|
||||
}
|
||||
/////////////////////////////
|
||||
// Speed is under limit
|
||||
else {
|
||||
mlSpeedCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::LimitEffect(cJointLimitEffect *pEffect) {
|
||||
cWorld3D *pWorld3D = mpWorld->GetWorld3D();
|
||||
|
||||
if (pWorld3D && pEffect->msSound != "") {
|
||||
cVector3f vVel(0, 0, 0);
|
||||
if (mpParentBody)
|
||||
vVel = mpChildBody->GetLinearVelocity() - mpParentBody->GetLinearVelocity();
|
||||
else
|
||||
vVel = mpChildBody->GetLinearVelocity();
|
||||
|
||||
float fSpeed = vVel.Length();
|
||||
if (fSpeed > pEffect->mfMaxSpeed)
|
||||
fSpeed = pEffect->mfMaxSpeed;
|
||||
|
||||
// Log("Speed: %f\n",fSpeed);
|
||||
|
||||
if (fSpeed >= pEffect->mfMinSpeed && mbHasCollided == false && pEffect->msSound != "") {
|
||||
float fVolume = (fSpeed - pEffect->mfMinSpeed) / (pEffect->mfMaxSpeed - pEffect->mfMinSpeed);
|
||||
|
||||
cSoundEntity *pSound = pWorld3D->CreateSoundEntity("LimitSound", pEffect->msSound, true);
|
||||
if (pSound) {
|
||||
pSound->SetVolume(fVolume);
|
||||
pSound->SetPosition(mpChildBody->GetLocalPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mbHasCollided = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::OnNoLimit() {
|
||||
mbHasCollided = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::Break() {
|
||||
mbBroken = true;
|
||||
mbBreakable = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool iPhysicsJoint::CheckBreakage() {
|
||||
if (mbBreakable == false)
|
||||
return false;
|
||||
|
||||
float fForcesSize = GetForce().Length();
|
||||
|
||||
if (fForcesSize >= mfBreakForce || mbBroken) {
|
||||
if (msBreakSound != "") {
|
||||
cWorld3D *pWorld3D = mpWorld->GetWorld3D();
|
||||
cSoundEntity *pSound = pWorld3D->CreateSoundEntity("BreakSound", msBreakSound, true);
|
||||
if (pSound)
|
||||
pSound->SetPosition(mvPivotPoint);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::CheckLimitAutoSleep(iPhysicsJoint *apJoint,
|
||||
const float afMin, const float afMax,
|
||||
const float afDist) {
|
||||
if (apJoint->mbLimitAutoSleep) {
|
||||
float fMinDiff = ABS(afMin - afDist);
|
||||
float fMaxDiff = ABS(afMax - afDist);
|
||||
|
||||
if (fMaxDiff < apJoint->mfLimitAutoSleepDist ||
|
||||
fMinDiff < apJoint->mfLimitAutoSleepDist) {
|
||||
if (apJoint->mlLimitStepCount >= apJoint->mlLimitAutoSleepNumSteps)
|
||||
apJoint->mpChildBody->DisableAfterSimulation();
|
||||
else
|
||||
apJoint->mlLimitStepCount++;
|
||||
} else {
|
||||
apJoint->mlLimitStepCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SAVE OBJECT STUFF
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
kBeginSerializeBase(cJointLimitEffect)
|
||||
kSerializeVar(msSound, eSerializeType_String)
|
||||
kSerializeVar(mfMinSpeed, eSerializeType_Float32)
|
||||
kSerializeVar(mfMaxSpeed, eSerializeType_Float32)
|
||||
kEndSerialize()
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
kBeginSerializeVirtual(cSaveData_iPhysicsJoint, iSaveData)
|
||||
kSerializeVar(msName, eSerializeType_String)
|
||||
|
||||
kSerializeVar(mlParentBodyId, eSerializeType_Int32)
|
||||
kSerializeVar(mlChildBodyId, eSerializeType_Int32)
|
||||
|
||||
kSerializeVar(m_mtxParentBodySetup, eSerializeType_Matrixf)
|
||||
kSerializeVar(m_mtxChildBodySetup, eSerializeType_Matrixf)
|
||||
|
||||
kSerializeVar(mvPinDir, eSerializeType_Vector3f)
|
||||
kSerializeVar(mvStartPivotPoint, eSerializeType_Vector3f)
|
||||
|
||||
kSerializeClassContainer(mlstControllers, cSaveData_iPhysicsController, eSerializeType_Class)
|
||||
|
||||
kSerializeVar(mMaxLimit, eSerializeType_Class)
|
||||
kSerializeVar(mMinLimit, eSerializeType_Class)
|
||||
|
||||
kSerializeVar(msMoveSound, eSerializeType_String)
|
||||
|
||||
kSerializeVar(mfMinMoveSpeed, eSerializeType_Float32)
|
||||
kSerializeVar(mfMinMoveFreq, eSerializeType_Float32)
|
||||
kSerializeVar(mfMinMoveFreqSpeed, eSerializeType_Float32)
|
||||
kSerializeVar(mfMinMoveVolume, eSerializeType_Float32)
|
||||
kSerializeVar(mfMaxMoveFreq, eSerializeType_Float32)
|
||||
kSerializeVar(mfMaxMoveFreqSpeed, eSerializeType_Float32)
|
||||
kSerializeVar(mfMaxMoveVolume, eSerializeType_Float32)
|
||||
kSerializeVar(mfMiddleMoveSpeed, eSerializeType_Float32)
|
||||
kSerializeVar(mfMiddleMoveVolume, eSerializeType_Float32)
|
||||
kSerializeVar(mMoveSpeedType, eSerializeType_Int32)
|
||||
|
||||
kSerializeVar(mbBreakable, eSerializeType_Bool)
|
||||
kSerializeVar(mfBreakForce, eSerializeType_Float32)
|
||||
kSerializeVar(msBreakSound, eSerializeType_String)
|
||||
kSerializeVar(mbBroken, eSerializeType_Bool)
|
||||
|
||||
kSerializeVar(msCallbackMaxFunc, eSerializeType_String)
|
||||
kSerializeVar(msCallbackMinFunc, eSerializeType_String)
|
||||
|
||||
kSerializeVar(mbAutoDeleteCallback, eSerializeType_Bool)
|
||||
kEndSerialize()
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iSaveData *iPhysicsJoint::CreateSaveData() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::SaveToSaveData(iSaveData *apSaveData) {
|
||||
kSaveData_SaveToBegin(iPhysicsJoint);
|
||||
|
||||
//////////////////////////
|
||||
// Variables
|
||||
kSaveData_SaveTo(msName);
|
||||
|
||||
kSaveData_SaveTo(m_mtxParentBodySetup);
|
||||
kSaveData_SaveTo(m_mtxChildBodySetup);
|
||||
|
||||
kSaveData_SaveTo(mvPinDir);
|
||||
kSaveData_SaveTo(mvStartPivotPoint);
|
||||
|
||||
kSaveData_SaveTo(mMaxLimit);
|
||||
kSaveData_SaveTo(mMinLimit);
|
||||
kSaveData_SaveTo(msMoveSound);
|
||||
kSaveData_SaveTo(mfMinMoveSpeed);
|
||||
kSaveData_SaveTo(mfMinMoveFreq);
|
||||
kSaveData_SaveTo(mfMinMoveFreqSpeed);
|
||||
kSaveData_SaveTo(mfMinMoveVolume);
|
||||
kSaveData_SaveTo(mfMaxMoveFreq);
|
||||
kSaveData_SaveTo(mfMaxMoveFreqSpeed);
|
||||
kSaveData_SaveTo(mfMaxMoveVolume);
|
||||
kSaveData_SaveTo(mfMiddleMoveSpeed);
|
||||
kSaveData_SaveTo(mfMiddleMoveVolume);
|
||||
kSaveData_SaveTo(mMoveSpeedType);
|
||||
kSaveData_SaveTo(mbBreakable);
|
||||
kSaveData_SaveTo(mfBreakForce);
|
||||
kSaveData_SaveTo(msBreakSound);
|
||||
kSaveData_SaveTo(mbBroken);
|
||||
|
||||
kSaveData_SaveTo(mbAutoDeleteCallback);
|
||||
|
||||
// Callback
|
||||
if (mpCallback && mpCallback->IsScript()) {
|
||||
cScriptJointCallback *pScriptCallback = static_cast<cScriptJointCallback *>(mpCallback);
|
||||
pData->msCallbackMaxFunc = pScriptCallback->msMaxFunc;
|
||||
pData->msCallbackMinFunc = pScriptCallback->msMinFunc;
|
||||
} else {
|
||||
pData->msCallbackMaxFunc = "";
|
||||
pData->msCallbackMinFunc = "";
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Controllers
|
||||
pData->mlstControllers.Clear();
|
||||
tPhysicsControllerMapIt it = m_mapControllers.begin();
|
||||
for (; it != m_mapControllers.end(); ++it) {
|
||||
iPhysicsController *pController = it->second;
|
||||
cSaveData_iPhysicsController saveController;
|
||||
pController->SaveToSaveData(&saveController);
|
||||
|
||||
pData->mlstControllers.Add(saveController);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Pointers
|
||||
kSaveData_SaveObject(mpParentBody, mlParentBodyId);
|
||||
kSaveData_SaveObject(mpChildBody, mlChildBodyId);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::LoadFromSaveData(iSaveData *apSaveData) {
|
||||
kSaveData_LoadFromBegin(iPhysicsJoint);
|
||||
|
||||
//////////////////////////
|
||||
// Variables
|
||||
kSaveData_LoadFrom(msName);
|
||||
|
||||
kSaveData_LoadFrom(m_mtxParentBodySetup);
|
||||
kSaveData_LoadFrom(m_mtxChildBodySetup);
|
||||
|
||||
kSaveData_LoadFrom(mvPinDir);
|
||||
kSaveData_LoadFrom(mvStartPivotPoint);
|
||||
|
||||
kSaveData_LoadFrom(mMaxLimit);
|
||||
kSaveData_LoadFrom(mMinLimit);
|
||||
kSaveData_LoadFrom(msMoveSound);
|
||||
kSaveData_LoadFrom(mfMinMoveSpeed);
|
||||
kSaveData_LoadFrom(mfMinMoveFreq);
|
||||
kSaveData_LoadFrom(mfMinMoveFreqSpeed);
|
||||
kSaveData_LoadFrom(mfMinMoveVolume);
|
||||
kSaveData_LoadFrom(mfMaxMoveFreq);
|
||||
kSaveData_LoadFrom(mfMaxMoveFreqSpeed);
|
||||
kSaveData_LoadFrom(mfMaxMoveVolume);
|
||||
kSaveData_LoadFrom(mfMiddleMoveSpeed);
|
||||
kSaveData_LoadFrom(mfMiddleMoveVolume);
|
||||
kSaveData_LoadFrom(mbBreakable);
|
||||
kSaveData_LoadFrom(mfBreakForce);
|
||||
kSaveData_LoadFrom(msBreakSound);
|
||||
kSaveData_LoadFrom(mbBroken);
|
||||
mMoveSpeedType = (ePhysicsJointSpeed)pData->mMoveSpeedType;
|
||||
|
||||
kSaveData_LoadFrom(mbAutoDeleteCallback);
|
||||
|
||||
//////////////////////////
|
||||
// Controllers
|
||||
cContainerListIterator<cSaveData_iPhysicsController> CtrlIt = pData->mlstControllers.GetIterator();
|
||||
while (CtrlIt.HasNext()) {
|
||||
cSaveData_iPhysicsController &saveCtrl = CtrlIt.Next();
|
||||
iPhysicsController *pController = mpWorld->CreateController(saveCtrl.msName);
|
||||
pController->LoadFromSaveData(&saveCtrl);
|
||||
|
||||
AddController(pController);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void iPhysicsJoint::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
|
||||
kSaveData_SetupBegin(iPhysicsJoint);
|
||||
|
||||
if (pData->msCallbackMaxFunc != "" || pData->msCallbackMinFunc != "") {
|
||||
cScriptJointCallback *pCallback = hplNew(cScriptJointCallback, (apGame->GetScene()));
|
||||
pCallback->msMaxFunc = pData->msCallbackMaxFunc;
|
||||
pCallback->msMinFunc = pData->msCallbackMinFunc;
|
||||
SetCallback(pCallback, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
} // namespace hpl
|
||||
Reference in New Issue
Block a user