Game Development Community

Crouch/Swim Anims(DSQ)?

by James Ford · in Torque Game Engine · 12/01/2008 (7:39 am) · 29 replies

I'm currently taking a look at integrating (or improving if necessary) the crouch/swim resources for TGEA you may have seen around the site.

My question is, would there happen to be any free crouching/swimming animations for the standard torque player around here? This is just for testing purposes.
Page «Previous 1 2
#1
12/01/2008 (7:42 am)
While they're not free (and you may already know, and if so please ignore this), the animations in this pack work with the crouching/crawling/swimming resource:

http://www.garagegames.com/products/172/

I have made some minor changes to TGEA that make the swimming look better if you're interested.
#2
12/02/2008 (6:12 am)
I would be interested in the files you changed to make it work with TGEA 1.7.1 I have tried 7 times now and never seem to get it merged in correctly at all
#3
12/02/2008 (6:58 am)
@Michael - I have this integrated into 1.7.1 with AFX. I have quite a few other things added in as well, or I'd just ship you the code (Cliff pack, SSAO, Ragdoll pack, Yack pack, doors pack, environment packs, etc).

I may be able to help if you have any specific questions, or are getting compiler errors, etc - feel free to post a note, and I'll see what I can do.
#4
12/03/2008 (6:46 am)
I will try again to merge it in tonioight and post any question I have.
#5
12/03/2008 (3:35 pm)
Ok First Issue is this

5. Next open "engine\game\gameConnectionMoves.cc" and go to about line 25 under
engine\game\gameConnecttionMoves.cc

In TGEA there is no such file
#6
12/03/2008 (4:28 pm)
GameConnectionMoves.cc is now engine/game/MoveManager.cpp

I found this by searching for this definition in the code:

F32 MoveManager::mForwardAction = 0;


PS - James, I hope you add walking also. :)
#7
12/03/2008 (5:17 pm)
6. Then open the file "engine\game\main.cc" with your C++ ide and go to about line 298 under
engine\game\main.cc
bool initGame(int argc, const char **argv
}
.
.
. Con::setIntVariable("$TypeMasks::DamagableItem ObjectType", DamagableItemObjectType);
Con::setIntVariable("$TypeMasks::InteriorMap ObjectType", InteriorMapObjectType);
.
.

Ok What about this I have searched the whole solution for each of these 3 lines.
#8
12/03/2008 (6:55 pm)
Hi Michael -

This is now in gameFunctions.cpp, around line 490. I think you didn't find it because the spacing in the line is now different (they lined up the columns to make it easier to read. Sometimes it's best to just look for keywords in the code rather than the whole line (I looked for "$TypeMasks::DamagableItemObjectType"

Jaimi
#9
12/03/2008 (9:09 pm)
Here is the swimming animation modifications - This uses the aligned particles resource to make the waves.


Man, youtube is terrible. The video looked much better than that before uploading, and I followed the guidelines to make it "high quality". I'm switching to wegame or vimeo.
#10
12/03/2008 (9:41 pm)
If you click thru to the youtube page there is a "watch in high def" link near the bottom of the video.

That effect looks pretty darn good for as simple as it is. We're experimenting with undulating water surfaces, but even then it might look better than nothing.
#11
12/05/2008 (8:40 am)
Ok When adding the climbing portion to AFX For TGEA

enum SimObjectTypes
{
.
.
.
StaticRenderedObjectType = BIT(26),
/// @}
/// @name Other
/// The following are allowed types that ...
/// @{
DamagableItemObjectType = BIT(27),
/// @}
ShadowCasterObjectType = BIT(28)
}

it says to add

ClimableItemObjectType = BIT(29)

but in AFX this is the code

// AFX CODE BLOCK (polysoup-type) <<
#if defined(AFX_CAP_AFXMODEL_TYPE) // AFX CODE BLOCK (afxModel-type) <<
   ShadowCasterObjectType =	     BIT(28),
   PolysoupObjectType =          BIT(29),
   afxModelObjectType =          BIT(30)
#else
   ShadowCasterObjectType =	     BIT(28),
   PolysoupObjectType =          BIT(29)
#endif // AFX CODE BLOCK (afxModel-type) >>

bit 29 and 30 are already accounted for. How did you over come this code section?
#12
12/05/2008 (8:48 am)
A "bit" of logical deduction should tell you that it will be bit(31). But with that if/else in there you might be better off placing the ClimableItemType before the AFX additions and increasing the AFX bitmasks accordingly.

EDIT: @Jaimi: nice video! I've been meaning to try that resource (particle alignment), and now that I've seen it in action I will definitely add that in.
#13
12/05/2008 (9:34 am)
I actually had already moved the afx bits up just like you said. I just forgot to come back in here and say it worked.
#14
12/05/2008 (12:04 pm)
Ok Having some major problems with the swim section of the torqemotion code

Error 7 error C2039: 'isPointSubmergedSimple' : is not a member of 'WaterBlock' d:\torque\afx112_combo_tgea171_sdk_tm\engine\source\t3d\player.cpp 2135


void Player::calculateSwim(VectorF* accVec , VectorF* moveVec , F32 moveSpeed)
{
	VectorF pv ;      		  
	mEnergy -= mDataBlock->swimEnergyDrain;      		  
	Point3F headRotation = getHeadRotation();      		  
	pv = *moveVec;		  		  
	pv *= moveSpeed;      		  
	F32 impulse = (5000 / mMass) * TickSec;     
	VectorF horiz = *moveVec;         		  
	horiz.normalize();         		  
	horiz *= 0.9;		  
	*accVec += horiz * impulse;         		  
	VectorF swimAcc = pv - (mVelocity + *accVec);      		  
	F32 swimSpeed = swimAcc.len();		  
	F32 maxSwimAcc = (mDataBlock->swimForce / mMass) * TickSec;      		  
	if (swimSpeed > maxSwimAcc) {        			  
		swimAcc *= maxSwimAcc / swimSpeed;			
	}		  
	if (swimSpeed > moveSpeed)			  
		swimSpeed = moveSpeed;		  
	*accVec += swimAcc;		  

	RayInfo rInfo;		        
	SimpleQueryList sql;		  
	if (isServerObject())			  
		gServerSceneGraph->getWaterObjectList(sql);		  
	else			  
		gClientSceneGraph->getWaterObjectList(sql);		

	F32 wtrSurface = 0;		  
	Point3F currentPos = getPosition();		  
	for (U32 i = 0; i < sql.mList.size(); i++)		  
	{			  
		WaterBlock* pBlock = dynamic_cast<WaterBlock*>(sql.mList[ i ]);			  

		if (pBlock) {				  
			if (pBlock->isPointSubmergedSimple(currentPos)) 					  
				wtrSurface = pBlock->getSurfaceHeight();			  
		}		  
	}		  
	if(currentPos.z > wtrSurface)			  
		wtrSurface = (currentPos.z - wtrSurface)*0.25;		  
	else			  
		wtrSurface = (wtrSurface - currentPos.z)*0.25;		  

	accVec->z = wtrSurface;
}

can you post your Player::calculateSwim code block because I am not seeing anything wrong here
#15
12/05/2008 (12:27 pm)
Yeah, that part needed quite a bit of tweaking. I'll post my changes here when I get home.
#16
12/05/2008 (12:40 pm)
Hi Guys, I'll see how I can help when I get home...

@ Jaimi McEntire wow that's really cool!
#17
12/05/2008 (6:10 pm)
Did you find the info?
#18
12/05/2008 (7:06 pm)
First, you need to fix a bug where water doesn't get detected:

www.garagegames.com/mg/forums/result.thread.php?qt=67852

It's for 1.03, but the fix works for 1.7.1 also. Then, replace your calculateSwim() function with this one:

void Player::calculateSwim(VectorF* accVec , VectorF* moveVec , F32 moveSpeed)
{
	VectorF pv ;      		  
	mEnergy -= mDataBlock->swimEnergyDrain;      		  
	Point3F headRotation = getHeadRotation();      		  
	pv = *moveVec;		  		  
	pv *= moveSpeed;      		  
	F32 impulse = (5000 / mMass) * TickSec;     
	VectorF horiz = *moveVec;         		  
	horiz.normalize();         		  
	horiz *= 0.9f;		  
	*accVec += horiz * impulse;         		  
	VectorF swimAcc = pv - (mVelocity + *accVec);      		  
	F32 swimSpeed = swimAcc.len();		  
	F32 maxSwimAcc = (mDataBlock->swimForce / mMass) * TickSec;      		  
	if (swimSpeed > maxSwimAcc) {        			  
		swimAcc *= maxSwimAcc / swimSpeed;			
	}		  
	if (swimSpeed > moveSpeed)			  
		swimSpeed = moveSpeed;		  
	*accVec += swimAcc;		  

	RayInfo rInfo;		        
	SimpleQueryList sql;		  
	if (isServerObject())			  
		gServerSceneGraph->getWaterObjectList(sql);		  
	else			  
		gClientSceneGraph->getWaterObjectList(sql);		

	F32 wtrSurface = 0;		  
	Point3F currentPos = getPosition();		  
	for (U32 i = 0; i < sql.mList.size(); i++)		  
	{			  
		WaterBlock* pBlock = dynamic_cast<WaterBlock*>(sql.mList[ i ]);			  

		if (pBlock) {				  
			if (pBlock->isUnderwater(currentPos)) 					  
				wtrSurface = pBlock->getCenter();		
		}		  
	}		  
	if(currentPos.z > wtrSurface)			  
		wtrSurface = (currentPos.z - wtrSurface)*0.25;		  
	else			  
		wtrSurface = (wtrSurface - currentPos.z)*0.25;		  

	accVec->z = wtrSurface;

}

Now the fun part comes. There is a giant function called UpdateMove that has to be modified as well. There's some code where it checks for 0.0 and 1.0 for water coverage. Well, that doesn't work. You'll need to replace these sections with more reasonable values. Here is what I did:

if(!Swimming && mWaterCoverage >= 0.75f) 
      {
         setPlayerAnimAct(Swim); 
         Swimming = true;
      }
      else if(Swimming && mWaterCoverage < 0.65f) {
         setPlayerAnimAct(Stand);          
         Swimming = false;
      }

if ( !inLiquid && mWaterCoverage >=  0.7f) // 1.0f) 
      {
         inLiquid = true;
      }
      else if ( inLiquid && mWaterCoverage < 0.5f ) // 0.8f)
      {
         if ( getVelocity().len() >= mDataBlock->exitSplashSoundVel && !isMounted() )
            SFX->playOnce( mDataBlock->sound[PlayerData::ExitWater], &getTransform() );
         inLiquid = false;
      }


      if ( !Swimming && mWaterCoverage >=  0.75f)
      {
         // TM :Basic Motion Pack
         setPlayerAnimAct(Swim);
         Swimming = true;
      }
      else if ( Swimming && mWaterCoverage < 0.65f )
      {
         // TM :Basic Motion Pack
         setPlayerAnimAct(Stand);
         Swimming = false;
      }

There are also some changes that I did to PickActionAnimation, but they just had to do with allowing the player to look like they were treading water. You'll want to play around with this function to get it to suit your own needs.
#19
12/05/2008 (7:38 pm)
Ok Looking in Shapebase.cpp in the AFX for TGEA repo

the water find function is commented out in the default repo

static void waterFind(SceneObject* obj,void * key)
{
/*
   ShapeBase* shape = reinterpret_cast<ShapeBase*>(key);
   WaterBlock* wb   = dynamic_cast<WaterBlock*>(obj);
   AssertFatal(wb != NULL, "Error, not a water block!");
   if (wb == NULL) {
      sWaterCoverage = 0;
      return;
   }

   const Box3F& wbox = obj->getWorldBox();
   const Box3F& sbox = shape->getWorldBox();
   sWaterType = 0;
   if (wbox.isOverlapped(sbox)) {
      sWaterType = wb->getLiquidType();
      if (wbox.max.z < sbox.max.z)
         sWaterCoverage = (wbox.max.z - sbox.min.z) / (sbox.max.z - sbox.min.z);
      else
         sWaterCoverage = 1;

      sWaterViscosity = wb->getViscosity();
      sWaterDensity   = wb->getDensity();
      sWaterHeight    = wb->getSurfaceHeight();
   }
*/
}
#20
12/05/2008 (7:59 pm)
Yes, just follow the instructions on the other thread.
Page «Previous 1 2