etqw-sdk/source/game/physics/Physics_SimpleSpline.cpp

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;
}