mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-16 00:01:53 +02:00
182 lines
4.1 KiB
C++
182 lines
4.1 KiB
C++
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "prey_local.h"
|
|
|
|
|
|
CLASS_DECLARATION( hhMoveable, hhBarrel )
|
|
END_CLASS
|
|
|
|
/*
|
|
================
|
|
hhBarrel::hhBarrel
|
|
================
|
|
*/
|
|
hhBarrel::hhBarrel() {
|
|
radius = 1.0f;
|
|
barrelAxis = 0;
|
|
lastOrigin.Zero();
|
|
lastAxis.Identity();
|
|
additionalRotation = 0.0f;
|
|
additionalAxis.Identity();
|
|
fl.networkSync = true;
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhBarrel::Save
|
|
================
|
|
*/
|
|
void hhBarrel::Save( idSaveGame *savefile ) const {
|
|
savefile->WriteFloat( radius );
|
|
savefile->WriteInt( barrelAxis );
|
|
savefile->WriteVec3( lastOrigin );
|
|
savefile->WriteMat3( lastAxis );
|
|
savefile->WriteFloat( additionalRotation );
|
|
savefile->WriteMat3( additionalAxis );
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhBarrel::Restore
|
|
================
|
|
*/
|
|
void hhBarrel::Restore( idRestoreGame *savefile ) {
|
|
savefile->ReadFloat( radius );
|
|
savefile->ReadInt( barrelAxis );
|
|
savefile->ReadVec3( lastOrigin );
|
|
savefile->ReadMat3( lastAxis );
|
|
savefile->ReadFloat( additionalRotation );
|
|
savefile->ReadMat3( additionalAxis );
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhBarrel::BarrelThink
|
|
================
|
|
*/
|
|
void hhBarrel::BarrelThink( void ) {
|
|
bool wasAtRest, onGround;
|
|
float movedDistance, rotatedDistance, angle;
|
|
idVec3 curOrigin, gravityNormal, dir;
|
|
idMat3 curAxis, axis;
|
|
|
|
wasAtRest = IsAtRest();
|
|
|
|
// run physics
|
|
RunPhysics();
|
|
|
|
// only need to give the visual model an additional rotation if the physics were run
|
|
if ( !wasAtRest ) {
|
|
|
|
// current physics state
|
|
onGround = GetPhysics()->HasGroundContacts();
|
|
curOrigin = GetPhysics()->GetOrigin();
|
|
curAxis = GetPhysics()->GetAxis();
|
|
|
|
// if the barrel is on the ground
|
|
if ( onGround ) {
|
|
gravityNormal = GetPhysics()->GetGravityNormal();
|
|
|
|
dir = curOrigin - lastOrigin;
|
|
dir -= gravityNormal * dir * gravityNormal;
|
|
movedDistance = dir.LengthSqr();
|
|
|
|
// if the barrel moved and the barrel is not aligned with the gravity direction
|
|
if ( movedDistance > 0.0f && idMath::Fabs( gravityNormal * curAxis[barrelAxis] ) < 0.7f ) {
|
|
|
|
// barrel movement since last think frame orthogonal to the barrel axis
|
|
movedDistance = idMath::Sqrt( movedDistance );
|
|
dir *= 1.0f / movedDistance;
|
|
movedDistance = ( 1.0f - idMath::Fabs( dir * curAxis[barrelAxis] ) ) * movedDistance;
|
|
|
|
// get rotation about barrel axis since last think frame
|
|
angle = lastAxis[(barrelAxis+1)%3] * curAxis[(barrelAxis+1)%3];
|
|
angle = idMath::ACos( angle );
|
|
// distance along cylinder hull
|
|
rotatedDistance = angle * radius;
|
|
|
|
// if the barrel moved further than it rotated about it's axis
|
|
if ( movedDistance > rotatedDistance ) {
|
|
|
|
// additional rotation of the visual model to make it look
|
|
// like the barrel rolls instead of slides
|
|
angle = 180.0f * (movedDistance - rotatedDistance) / (radius * idMath::PI);
|
|
if ( gravityNormal.Cross( curAxis[barrelAxis] ) * dir < 0.0f ) {
|
|
additionalRotation += angle;
|
|
} else {
|
|
additionalRotation -= angle;
|
|
}
|
|
dir = vec3_origin;
|
|
dir[barrelAxis] = 1.0f;
|
|
additionalAxis = idRotation( vec3_origin, dir, additionalRotation ).ToMat3();
|
|
}
|
|
}
|
|
}
|
|
|
|
// save state for next think
|
|
lastOrigin = curOrigin;
|
|
lastAxis = curAxis;
|
|
}
|
|
|
|
Present();
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhBarrel::Think
|
|
================
|
|
*/
|
|
void hhBarrel::Think( void ) {
|
|
if ( thinkFlags & TH_THINK ) {
|
|
if ( !FollowInitialSplinePath() ) {
|
|
BecomeInactive( TH_THINK );
|
|
}
|
|
}
|
|
|
|
BarrelThink();
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhBarrel::GetPhysicsToVisualTransform
|
|
================
|
|
*/
|
|
bool hhBarrel::GetPhysicsToVisualTransform( idVec3 &origin, idMat3 &axis ) {
|
|
origin = vec3_origin;
|
|
axis = additionalAxis;
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhBarrel::Spawn
|
|
================
|
|
*/
|
|
void hhBarrel::Spawn( void ) {
|
|
const idBounds &bounds = GetPhysics()->GetBounds();
|
|
|
|
// radius of the barrel cylinder
|
|
radius = ( bounds[1][0] - bounds[0][0] ) * 0.5f;
|
|
|
|
// always a vertical barrel with cylinder axis parallel to the z-axis
|
|
barrelAxis = 2;
|
|
|
|
lastOrigin = GetPhysics()->GetOrigin();
|
|
lastAxis = GetPhysics()->GetAxis();
|
|
|
|
additionalRotation = 0.0f;
|
|
additionalAxis.Identity();
|
|
}
|
|
|
|
/*
|
|
================
|
|
hhBarrel::ClientPredictionThink
|
|
================
|
|
*/
|
|
void hhBarrel::ClientPredictionThink( void ) {
|
|
Think();
|
|
}
|
|
|
|
|