Page 1 of 2

Spring.UnitPieceTurnVec(UnitID, normedVecX, normedVecY, norm

Posted: 11 Jun 2014, 09:08
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..

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

Posted: 10 Aug 2014, 23:27
by 9heart
Quaternions are useful. Unfortunately Spring can't use them.

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

Posted: 12 Aug 2014, 10:39
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

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

Posted: 12 Aug 2014, 11:31
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.

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

Posted: 12 Aug 2014, 12:36
by jK
PicassoCT wrote:Spring uses Quaternions for the internal rotations
?
no?
It uses simple matrix math

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

Posted: 15 Aug 2014, 06:20
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 ); 
} 

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

Posted: 15 Aug 2014, 06:46
by smoth
what's the difference, would it look any different from what we currently use to animate?

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

Posted: 15 Aug 2014, 07:03
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 =)

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

Posted: 15 Aug 2014, 08:13
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

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

Posted: 15 Aug 2014, 09:43
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?

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

Posted: 15 Aug 2014, 16:11
by PicassoCT
jK is not a suggestion man :)

More the sort of - i made this- take it or leave it man.

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

Posted: 15 Aug 2014, 20:15
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;

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

Posted: 15 Aug 2014, 21:37
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

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

Posted: 15 Aug 2014, 21:49
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?

...

}

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

Posted: 15 Aug 2014, 22:00
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

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

Posted: 11 Dec 2014, 22:21
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?

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

Posted: 11 Dec 2014, 23:09
by jK
I don't understand a single thing what you said.

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

Posted: 11 Dec 2014, 23:56
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?

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

Posted: 12 Dec 2014, 02:35
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.

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

Posted: 12 Dec 2014, 02:37
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