Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY, norm

Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY, norm

Requests for features in the spring code.

Moderator: Moderators

User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY, norm

Post by PicassoCT »

Something similar to this.. avoiding the whole raidan/angle whatever pit

Code: Select all

int CLuaUnitScript::TurnVec(lua_State* L)
{
	if (activeScript == NULL) {
	return 0;
	}
//
const int piece = 	luaL_checkint(L, 1) - 1;
const float x_vec=	luaL_checkfloat(L, 2);
const float y_vec=	luaL_checkfloat(L, 3);
const float z_vec=	luaL_checkfloat(L, 4);
const float xspeed=	luaL_checkfloat(L, 5);
const float yspeed=	luaL_checkfloat(L, 6);
const float zspeed=	luaL_checkfloat(L, 7);
const float zspeed=	luaL_checkfloat(L, 7);

const float destx =GetHeadingFromVector(1,x_vec);
const float desty =GetHeadingFromVector(1,y_vec);
const float destz =GetHeadingFromVector(1,z_vec);

	if (yspeed == 0.0f || yspeed==0.0f || zspeed== 0.0f)
	{
	activeScript->TurnNow(piece, 1, destx);
	activeScript->TurnNow(piece, 2, desty);
	activeScript->TurnNow(piece, 3, destz);
	}

	if (lua_isboolean(L, 8) && lua_toboolean(L, 8)) {
	// CUnit* unit = activeScript->GetUnit();
	// LocalModel* model = unit->localModel;
	LocalModelPiece* piece = ParseLocalModelPiece(L, activeScript, __FUNCTION__);

	// note:
	// both of these only have effect if MoveNow() was called, but
	// the former starts from the ROOT piece (less efficient here)
	// model->UpdatePieceMatrices();
	piece->UpdateMatricesRec(true);
	}

return 0;

}
Insert it into:
https://github.com/spring/spring/blob/ ... Script.cpp

also add:

Code: Select all

static int TurnVec(lua_State* L);
to the non-private parts of :
https://github.com/spring/spring/blob/e ... itScript.h

Allmoist like a patch.. but can not pushed, as my hand was git-crippled by a rogue version-system..
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

Quaternions are useful. Unfortunately Spring can't use them.
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by PicassoCT »

Spring uses Quaternions for the internal rotations, otherwise, you would see strange turning behaviour... there is no extrapolating of a rotation with the euler-angles that wouldnt run in some strange cases.

Still the vector turning would be some neat thing..

I made a pull request for this..

https://github.com/spring/spring/pull/120
User avatar
Anarchid
Posts: 1384
Joined: 30 Nov 2008, 04:31

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by Anarchid »

Spring uses Quaternions for the internal rotations, otherwise, you would see strange turning behaviour... there is no extrapolating of a rotation with the euler-angles that wouldnt run in some strange cases.
Can you manage a source line link? Because i'm pretty sure spring has no quaternions anywhere and you can have that "strange turning behaviour" as much as you please, from gimbal lock to inelegant turns.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by jK »

PicassoCT wrote:Spring uses Quaternions for the internal rotations
?
no?
It uses simple matrix math
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

Image

Code: Select all

//Creates a new Matrix that rotates piece around an arbitrary vector.
void Spring.UnitPieceLookAt(const vector3& dir, const vector3& up, matrix33& m) { 
        vector3 z(dir); 
        z.norm(); 
        vector3 x( up * z ); // x = up cross z 
        x.norm(); 
        vector3 y( z * x ); // y = z cross x 
        m.set_components(x,y,z ); 
} 
User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by smoth »

what's the difference, would it look any different from what we currently use to animate?
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

would not look any different

but using Turn/Move to orient pieces to point towards a particular vector is abysmally shit

we need to compute piece rotation matrices without turn/move indirection

then the possibilities for better animations increase =)
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by jK »

9heart wrote:would not look any different

but using Turn/Move to orient pieces to point towards a particular vector is abysmally shit

we need to compute piece rotation matrices without turn/move indirection

then the possibilities for better animations increase =)
the opposite
turn/move are ANIMATED systems -> you can interpolate them
with your direct write to matrix system you cannot blend multiple animations
making stuff worse
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

those are good points, but am not saying throw out Turn/Move altogether, just that all move/turn does is update the rotation matrix at the appropriate time

Code: Select all

bool LocalModelPiece::UpdateMatrix()
{
	return (original->ComposeTransform(pieceSpaceMat.LoadIdentity(), pos, rot, original->scales));
}

Code: Select all

struct S3DModelPiece {
....
CMatrix44f& ComposeRotation(CMatrix44f& m, const float3& r) const {
		// execute rotations in YPR order by default
		// note: translating + rotating is faster than
		// matrix-multiplying (but the branching hurts)
                switch (axisMapType) {
			case AXIS_MAPPING_XYZ: {
				if (r.y != 0.0f) { m.RotateY(r.y * rotAxisSigns.y); } // yaw
				if (r.x != 0.0f) { m.RotateX(r.x * rotAxisSigns.x); } // pitch
				if (r.z != 0.0f) { m.RotateZ(r.z * rotAxisSigns.z); } // roll


that being able to update the rotation matrix of pieces without the use of turn/move would be nice, in certain situations (inverse kinematics)

jK, if you have another suggestion?
User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 10450
Joined: 24 Jan 2006, 21:12

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by PicassoCT »

jK is not a suggestion man :)

More the sort of - i made this- take it or leave it man.
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

Lets have a look at the animation code. I am not engine dev, I am not opengl Guru...

but project open source so maybe lets try improving things for rotating pieces


Code: Select all

enum AnimType {ANone = -1, ATurn = 0, ASpin = 1, AMove = 2};

void CUnitScript::TickAnims(int deltaTime, AnimType type, std::list< std::list<AnimInfo*>::iterator >& doneAnims) {
	switch (type) {
		case AMove: {
			for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) {
				AnimInfo* ai = *it;

				// NOTE: we should not need to copy-and-set here, because
				// MoveToward/TurnToward/DoSpin modify pos/rot by reference
				float3 pos = pieces[ai->piece]->GetPosition();

				if (MoveToward(pos[ai->axis], ai->dest, ai->speed / (1000 / deltaTime))) {
					ai->done = true; doneAnims.push_back(it);
				}

				pieces[ai->piece]->SetPosition(pos);
				unit->localModel->PieceUpdated(ai->piece);
			}
		} break;

		case ATurn: {
			for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) {
				AnimInfo* ai = *it;
				float3 rot = pieces[ai->piece]->GetRotation();

				if (TurnToward(rot[ai->axis], ai->dest, ai->speed / (1000 / deltaTime))) {
					ai->done = true; doneAnims.push_back(it);
				}

				pieces[ai->piece]->SetRotation(rot);
				unit->localModel->PieceUpdated(ai->piece);
			}
		} break;

		case ASpin: {
			for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) {
				AnimInfo* ai = *it;
				float3 rot = pieces[ai->piece]->GetRotation();

				if (DoSpin(rot[ai->axis], ai->dest, ai->speed, ai->accel, 1000 / deltaTime)) {
					ai->done = true; doneAnims.push_back(it);
				}

				pieces[ai->piece]->SetRotation(rot);
				unit->localModel->PieceUpdated(ai->piece);
			}
		} break;

		default: {
		} break;
	}
}

Maybe possible to do something like:


Code: Select all


enum AnimType {ANone = -1, ATurn = 0, ASpin = 1, AMove = 2, ASwing = 3};

struct AnimInfo {
		AnimType type;
		int axis;
		int piece;
		float speed;
		float dest;           // means final position when turning or moving, final speed when spinning
		float accel;            // used for spinning, can be negative
               vector3 target;         // use for swing
		bool done;
		std::list<IAnimListener*> listeners;
	};
...



....
                 /*The purpose of the swing motion is to orientate the piece limb in a prescribed direction
given by a unit vector 

To transform the z vector into the d vector, a rotation matrix
must be defined.

 Do not interpolate matrices
 tR1 + (1-t)R2 is not a rotation!*/

		case ASwing {
			for (std::list<AnimInfo*>::iterator it = anims[type].begin(); it != anims[type].end(); ++it) {
				AnimInfo* ai = *it;
				
                                Matrix4x4 rot = pieces[ai->piece]->GetRotationMatrix();

				if (SwingToward(ai->target)) {
					ai->done = true; doneAnims.push_back(it);
				}

				pieces[ai->piece]->SetRotationMatrix(rot);
				unit->localModel->PieceUpdated(ai->piece);
			}
		} break;
User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by smoth »

PicassoCT wrote:jK is not a suggestion man :)

More the sort of - i made this- take it or leave it man.
jk has a valid point.

Dunno what his thoughts are on it. I am just wondering how this thing is supposed to make it all better
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

You can build a rotation matrix to rotate about any arbitrary axis like this:

Image

Where

c = cos (theta)
s = sin (theta)
t = 1 - cos (theta)

and (x,y,z) is a unit vector on the axis of rotation

Code: Select all

/**
 * @brief Updates Swing animation, used to rotate object about rotationAxis by rotationAngle
 * @param dest vector3 target
 * @return returns true if destination was reached, false otherwise
 */
bool CUnitScript::SwingToward(vector3 )
{

...considerations...

Left or right handed coordinate system?
Vector shown as row or column ?
Matrix order?
Direction of x,y and z coordinates?
Euler angle order?
Direction of positive angles?
Choice of basis?

...

}
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

smoth wrote: I am just wondering how this thing is supposed to make it all better
The purpose of the swing motion is to orientate the outgoing limb in a prescribed direction
given by a unit vector

Sometimes (inverse kinematics anyone?) we are given a point x-y-z in the World Space, and we want to orient the piece so that its forward vector points towards the position (x,y,z)



Previously this would require lots of trigonometry and issues with gimbal lock, euler angles...

basically parameterizing the rotation this way makes it a lot easier to work with

As jK said, no interpolation, no animation, but:

Code: Select all

if walking
  calculate_ik()
  apply_rotations()
end
if you can update the rotation matrix in the unit script, via SwingTowards anim, then each frame (or sim frame?) perform checks on various joint constraints/positions and change rotation accordingly.

which is simply too difficult if not impossible with euler angle parameterization

Use Swing to rotate objects about their center of gravity, or to rotate a foot around an ankle or an ankle around a knee
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

Does any of my previous post make sense to anyone ?

I still think its a good idea..

maybe a dev can point out any potential problems before I try implementing it?
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by jK »

I don't understand a single thing what you said.
Super Mario
Posts: 823
Joined: 21 Oct 2008, 02:54

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by Super Mario »

9heart wrote:You can build a rotation matrix to rotate about any arbitrary axis like this:

Image
How exactly did you derived that may I ask?
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

jK wrote:I don't understand a single thing what you said.
I just want to define a point in arbitrary space, and an arbitrary piece axis, and turn the piece to face that point, from a LUA Script.

This is impossible with TURN/MOVE commands. Requires a method to change piece 3x3 rotation matrix from LUA.
9heart
Posts: 55
Joined: 16 Sep 2010, 16:14

Re: Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY,

Post by 9heart »

Super Mario wrote:
9heart wrote:You can build a rotation matrix to rotate about any arbitrary axis like this:

Image
How exactly did you derived that may I ask?
http://en.wikipedia.org/wiki/Linear_algebra
Post Reply

Return to “Feature Requests”