211 lines
4.9 KiB
C++
211 lines
4.9 KiB
C++
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
|
||
|
#include "../precompiled.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
#include "Physics_SimpleSpline.h"
|
||
|
|
||
|
/*
|
||
|
===============================================================
|
||
|
|
||
|
sdPhysics_SimpleSpline
|
||
|
|
||
|
===============================================================
|
||
|
*/
|
||
|
|
||
|
CLASS_DECLARATION( idPhysics_Base, sdPhysics_SimpleSpline )
|
||
|
END_CLASS
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::sdPhysics_SimpleSpline
|
||
|
================
|
||
|
*/
|
||
|
sdPhysics_SimpleSpline::sdPhysics_SimpleSpline( void ) {
|
||
|
current.worldAxes.Identity();
|
||
|
current.worldOrigin.Zero();
|
||
|
current.acceleration.Zero();
|
||
|
current.velocity.Zero();
|
||
|
current.time = 0;
|
||
|
|
||
|
saved = current;
|
||
|
|
||
|
clipModel = NULL;
|
||
|
isOrientated = false;
|
||
|
startTime = -1;
|
||
|
totalTime = 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::~sdPhysics_SimpleSpline
|
||
|
================
|
||
|
*/
|
||
|
sdPhysics_SimpleSpline::~sdPhysics_SimpleSpline( void ) {
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::Evaluate
|
||
|
================
|
||
|
*/
|
||
|
idVec3 sdPhysics_SimpleSpline::EvaluatePosition( void ) const {
|
||
|
if ( !spline.Num() ) {
|
||
|
return vec3_origin;
|
||
|
}
|
||
|
|
||
|
float frac;
|
||
|
const splineType_t& section = GetSplineInfo( gameLocal.time, frac );
|
||
|
|
||
|
return section.GetCurrentValue( frac );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::Evaluate
|
||
|
================
|
||
|
*/
|
||
|
bool sdPhysics_SimpleSpline::Evaluate( int timeStepMSec, int endTimeMSec ) {
|
||
|
if ( !spline.Num() ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/* int i;
|
||
|
for ( i = 0; i < spline.Num(); i++ ) {
|
||
|
const idCurve_CubicBezier< idVec3 >& section = spline[ i ];
|
||
|
float index = 0.f;
|
||
|
idVec3 lastPos = section.GetCurrentValue( index );
|
||
|
idVec3 pos;
|
||
|
for ( index += 0.01f; index <= 1.f; index += 0.01f ) {
|
||
|
pos = section.GetCurrentValue( index );
|
||
|
gameRenderWorld->DebugLine( colorGreen, lastPos, pos );
|
||
|
lastPos = pos;
|
||
|
}
|
||
|
}*/
|
||
|
|
||
|
|
||
|
idVec3 oldOrigin = current.worldOrigin;
|
||
|
idMat3 oldWorldAxes = current.worldAxes;
|
||
|
|
||
|
float frac;
|
||
|
const splineType_t& section = GetSplineInfo( endTimeMSec, frac );
|
||
|
|
||
|
current.acceleration = section.GetCurrentSecondDerivative( frac );
|
||
|
current.velocity = section.GetCurrentFirstDerivative( frac );
|
||
|
current.worldOrigin = section.GetCurrentValue( frac );
|
||
|
|
||
|
if ( clipModel ) {
|
||
|
clipModel->Link( gameLocal.clip, self, 0, current.worldOrigin, current.worldAxes );
|
||
|
}
|
||
|
|
||
|
current.time = endTimeMSec;
|
||
|
|
||
|
return ( current.worldOrigin != oldOrigin ) || ( current.worldAxes != oldWorldAxes );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::SetSpline
|
||
|
================
|
||
|
*/
|
||
|
void sdPhysics_SimpleSpline::SetSpline( int _startTime, const idList< splineType_t >& _spline, const idList< int >& _splineTimes ) {
|
||
|
startTime = _startTime;
|
||
|
splineTimes = _splineTimes;
|
||
|
spline = _spline;
|
||
|
totalTime = 0;
|
||
|
|
||
|
int i;
|
||
|
for ( i = 0; i < _splineTimes.Num(); i++ ) {
|
||
|
totalTime += _splineTimes[ i ];
|
||
|
}
|
||
|
|
||
|
assert( splineTimes.Num() == spline.Num() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::GetSplineInfo
|
||
|
================
|
||
|
*/
|
||
|
const sdPhysics_SimpleSpline::splineType_t& sdPhysics_SimpleSpline::GetSplineInfo( int endTimeMSec, float& fraction ) const {
|
||
|
int timeSinceStart = endTimeMSec - startTime;
|
||
|
int i;
|
||
|
for ( i = 0; i < spline.Num(); i++ ) {
|
||
|
if ( timeSinceStart > splineTimes[ i ] ) {
|
||
|
timeSinceStart -= splineTimes[ i ];
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
fraction = idMath::ClampFloat( 0.f, 1.f, timeSinceStart / ( float )splineTimes[ i ] );
|
||
|
return spline[ i ];
|
||
|
}
|
||
|
|
||
|
fraction = 1.f;
|
||
|
return spline[ spline.Num() - 1 ];
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::SetAxis
|
||
|
================
|
||
|
*/
|
||
|
void sdPhysics_SimpleSpline::SetAxis( const idMat3& newAxis, int id ) {
|
||
|
current.worldAxes = newAxis;
|
||
|
|
||
|
if ( clipModel ) {
|
||
|
clipModel->Link( gameLocal.clip, self, 0, current.worldOrigin, current.worldAxes );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::SetOrigin
|
||
|
================
|
||
|
*/
|
||
|
void sdPhysics_SimpleSpline::SetOrigin( const idVec3& newOrigin, int id ) {
|
||
|
current.worldOrigin = newOrigin;
|
||
|
|
||
|
if ( clipModel ) {
|
||
|
clipModel->Link( gameLocal.clip, self, 0, current.worldOrigin, current.worldAxes );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::IsAtRest
|
||
|
================
|
||
|
*/
|
||
|
bool sdPhysics_SimpleSpline::IsAtRest( void ) const {
|
||
|
return current.time >= ( startTime + totalTime );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::GetAbsBounds
|
||
|
================
|
||
|
*/
|
||
|
const idBounds& sdPhysics_SimpleSpline::GetAbsBounds( int id ) const {
|
||
|
current.absBounds.Clear();
|
||
|
current.absBounds.AddPoint( current.mins + current.worldOrigin );
|
||
|
current.absBounds.AddPoint( current.maxs + current.worldOrigin );
|
||
|
|
||
|
return current.absBounds;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
sdPhysics_SimpleSpline::SetBounds
|
||
|
================
|
||
|
*/
|
||
|
void sdPhysics_SimpleSpline::SetBounds( const idVec3& mins, const idVec3& maxs ) {
|
||
|
current.mins = mins;
|
||
|
current.maxs = maxs;
|
||
|
}
|