T3D 360 Directional Movement plus Double Jump (Source Code Updated)
by Kevin Mitchell · in Torque 3D Professional · 06/27/2011 (5:56 pm) · 13 replies
Player.cpp
Line 58
-Before
// Downward velocity at which we consider the player falling static const F32 sFallingThreshold = -10.0f;
-After
// Downward velocity at which we consider the player falling static const F32 sFallingThreshold = -10.0f;
Line 206
-Before
shadowProjectionDistance = 14.0f; renderFirstPerson = true;
-After
shadowProjectionDistance = 14.0f; DIR_ANGLE=4.712389; //forward delta renderFirstPerson = true;
Line 533
-Before
void PlayerData::initPersistFields()
{
addField( "pickupRadius", TypeF32, Offset(pickupRadius, PlayerData),-After
void PlayerData::initPersistFields()
{
addField( "DIR_ANGLE", TypeF32, Offset(DIR_ANGLE, PlayerData),
"@brief angle of main node z rotation nn");
addField( "pickupRadius", TypeF32, Offset(pickupRadius, PlayerData),Line 1295
-Before
mFalling = false; mSwimming = false;
-After
mFalling = false; hasDoubleJumped = false; mSwimming = false;
Line 1945
-Before
}
}
void Player::setPose( Pose pose )
{-After
}
}
float CalcTheta( const Point3F Point1, const Point3F Point2 )
{
float Theta;
if ( Point2.x - Point1.x == 0 ){
if ( Point2.y > Point1.y ){
Theta = 0;
}else{
Theta = static_cast<float>( M_PI_F );
}
}else{
Theta = std::atan( (Point2.y - Point1.y) / (Point2.x - Point1.x) );
if ( Point2.x > Point1.x ){
Theta = static_cast<float>( M_PI_F ) / 2.0f - Theta;
}else{
Theta = static_cast<float>( M_PI_F ) * 1.5f - Theta;
}
}
return Theta;
}
void Player::setPose( Pose pose )
{Line 2088
-Before
delta.head = mHead;
delta.headVec -= mHead;
}
MatrixF zRot;
zRot.set(EulerF(0.0f, 0.0f, mRot.z));
// Desired move direction & speed-After
delta.head = mHead;
delta.headVec -= mHead;
}
//CHANGE FOR NODE ROTATION
if(move->y||move->x){
Point3F Point1;
Point3F Point2;
Point1.x=10;
Point1.y=10;
Point1.z=0;
Point2.x=10-(move->y);
Point2.y=10+move->x;
Point2.z=0;
//(CalcTheta(Point1,Point2)*180)/M_PI_F; // angle in degrees
mDataBlock->DIR_ANGLE = CalcTheta(Point1,Point2);
Point3F _pos;
_pos.set(0,0,0);
Point3F _axis;
_axis.set(0,0,1);
QuatF _rot;
F32 y2 = move->yaw/2;
if (y2 > M_PI_F)
y2 -= M_2PI_F;
mDataBlock->DIR_ANGLE-=y2;
if (mDataBlock->DIR_ANGLE <0)
mDataBlock->DIR_ANGLE += M_2PI_F;
_rot.set(_axis,mDataBlock->DIR_ANGLE);
String _name;
_name="Bip01";
mDataBlock->mShape->setNodeTransform(_name, _pos,_rot);
//Con::printf("Node _pos: %f %f %f : < %f ::: %f",_rot.x,_rot.y,_rot.z,_rot.w, mDataBlock->DIR_ANGLE);
}else{
Point3F _pos;
_pos.set(0,0,0);
Point3F _axis;
_axis.set(0,0,1);
QuatF _rot;
F32 y2 = move->yaw/2;
if (y2 > M_PI_F)
y2 -= M_2PI_F;
mDataBlock->DIR_ANGLE-=y2;
if (mDataBlock->DIR_ANGLE <0)
mDataBlock->DIR_ANGLE += M_2PI_F;
_rot.set(_axis,mDataBlock->DIR_ANGLE);
String _name;
_name="Bip01";
mDataBlock->mShape->setNodeTransform(_name, _pos,_rot);
}
//CHANGE FOR NODE ROTATION END
MatrixF zRot;
zRot.set(EulerF(0.0f, 0.0f, mRot.z));Line 2353
-Before
// Acceleration from Jumping
if (move->trigger[2] && canJump())// !isMounted() &&
{
// Scale the jump impulse base on maxJumpSpeed
F32 zSpeedScale = mVelocity.z;-After
// Acceleration from Jumping
if (move->trigger[2] && canJump())// !isMounted() &&
{
if(mFalling){
hasDoubleJumped=true;
}
// Scale the jump impulse base on maxJumpSpeed
F32 zSpeedScale = mVelocity.z;Line 2519
-Before
if (runSurface)
mFalling = false;
else
{
VectorF vel;
mWorldToObj.mulV(mVelocity,&vel);
mFalling = vel.z < sFallingThreshold;
}-After
if (runSurface){
hasDoubleJumped=false;
mFalling = false;
}else{
VectorF vel;
mWorldToObj.mulV(mVelocity,&vel);
mFalling = vel.z < sFallingThreshold;
}Line 2621
-Before
bool Player::canJump()
{
return mState == MoveState && mDamageState == Enabled && !isMounted() && !mJumpDelay && mEnergy >= mDataBlock->minJumpEnergy && mJumpSurfaceLastContact < JumpSkipContactsMax && !mSwimming;
}-After
bool Player::canJump()
{
return (mState == MoveState && mDamageState == Enabled && !isMounted() && !mJumpDelay && mEnergy >= mDataBlock->minJumpEnergy && mJumpSurfaceLastContact < JumpSkipContactsMax && !mSwimming)||(mFalling && hasDoubleJumped==false);
}Line 3179
-Before
// Pick animation that is the best fit for our current (local) velocity.
// Assumes that the root (stationary) animation is at startAnim.
F32 curMax = -0.1f;
for (U32 i = startAnim+1; i <= endAnim; i++)
{-After
// Pick animation that is the best fit for our current (local) velocity.
// Assumes that the root (stationary) animation is at startAnim.
F32 curMax = -0.1f;
//Overrides the check for strife and backwards
if(true){
*action = startAnim+1;
*forward = true;
return;
}
for (U32 i = startAnim+1; i <= endAnim; i++)
{Line 3590
-Before
totalMotion += velLen * dt;
mFalling = false;-After
totalMotion += velLen * dt;
hasDoubleJumped=false;
mFalling = false;Player.h
Line 39
-Before
bool renderFirstPerson; ///< Render the player shape in first person F32 pickupRadius; ///< Radius around player for items (on server)
-After
bool renderFirstPerson; ///< Render the player shape in first person F32 DIR_ANGLE; F32 pickupRadius; ///< Radius around player for items (on server)
Line 379
-Before
ActionState mState; ///< What is the player doing? @see ActionState bool mFalling; ///< Falling in mid-air? S32 mJumpDelay; ///< Delay till next jump
-After
ActionState mState; ///< What is the player doing? @see ActionState bool mFalling; ///< Falling in mid-air? bool hasDoubleJumped; ///< Jumping in mid-air? S32 mJumpDelay; ///< Delay till next jump
Note:
These should all be the same since there is always a forward run.
maxForwardSpeed = 12;//12//8 maxBackwardSpeed = 12; maxSideSpeed = 12;
Link back to resource
About the author
Riding Solo since 2005. Current Project: Fated World 2005-Present RPG Engine Tool Kit - Now available.
#2
06/27/2011 (6:01 pm)
Tying to get it posted but i guess there's a text limit. lol
#3
06/27/2011 (6:04 pm)
Grrr. I'll just write a line by line insert of the code changes. Gove me a sec.
#4
06/27/2011 (6:42 pm)
Updated and ready to go.
#5
07/14/2011 (5:43 pm)
@Kevin, I have just added your code changes with the soldier character released with T3D 1.1 and his animations aren't matching up with the directions. Is it something I did or with the soldier character.
#6
07/14/2011 (8:44 pm)
Ones his center node has to be called biped01 and the rig mught have to match a biped from max. Send me your player c and h. Kmitchell.12catblackstudios@gmail.com
#7
07/15/2011 (2:30 am)
Email sent
#8
07/17/2011 (6:47 pm)
Kevin did you ever figure that out for tek? whats needed for the soldier?
#9
07/17/2011 (6:57 pm)
The animation for soldier was not center to 0 for the body's main node.
#10
i was gonns use the soldier to test but probably just going to use my max bip instead
07/17/2011 (7:06 pm)
ok thanks.i was gonns use the soldier to test but probably just going to use my max bip instead
#11
If you plan to use your own character make sure it has the Bip01 node as the parent. If not then the character will not rotate like it's suppose to.
07/17/2011 (7:26 pm)
@Jordan, Kevin and I have figured out what the problem was. The code works great. The problem is in the soldier animations not lining up with the Y axis. In order to use the soldier with Kevin's code, you much open the soldiers max file and change the alignment of this animations and re-export them.If you plan to use your own character make sure it has the Bip01 node as the parent. If not then the character will not rotate like it's suppose to.
#12
05/08/2016 (9:04 pm)
Now your talking, i've searched this for an entire day non-stop.
#13
05/09/2016 (5:51 am)
glad it helpped.
Torque 3D Owner Bloodknight
Bloodknight Studios
edit: i swear... there was no code there when i first looked... and no, i havent been drinking!