示例#1
0
//Returns true if there was an animation to listen to
bool CUnitScript::AddAnimListener(AnimType type, int piece, int axis, IAnimListener *listener)
{
	std::list<AnimInfo*>::iterator animInfoIt = FindAnim(type, piece, axis);

	if (animInfoIt != anims[type].end()) {
		AnimInfo* ai = *animInfoIt;

		if (!ai->done) {
			ai->listeners.push_back(listener);
			return true;
		}

		// if the animation is already finished, listening for
		// it just adds some overhead since either the current
		// or the next Tick will remove it and call UnblockAll
		// (which calls AnimFinished for each listener)
		//
		// we could notify the listener here, but a cleaner way
		// is to treat the animation as if it did not exist and
		// simply disregard the WaitFor* (no side-effects)
		//
		// listener->AnimFinished(ai->type, ai->piece, ai->axis);
	}

	return false;
}
示例#2
0
void CVertMeshInstance::PlayAnimInternal(const char *AnimName, float Rate, bool Looped)
{
	guard(CVertMeshInstance::PlayAnimInternal);

	int NewAnimIndex = FindAnim(AnimName);
	if (NewAnimIndex == INDEX_NONE)
	{
		// show default pose
		AnimIndex  = INDEX_NONE;
		AnimTime   = 0;
		AnimRate   = 0;
		AnimLooped = false;
		return;
	}

	AnimRate   = (NewAnimIndex != INDEX_NONE) ? pMesh->AnimSeqs[NewAnimIndex].Rate * Rate : 0;
	AnimLooped = Looped;

	if (NewAnimIndex == AnimIndex && Looped)
	{
		// animation not changed, just set some flags (above)
		return;
	}

	AnimIndex = NewAnimIndex;
	AnimTime  = 0;

	unguard;
}
示例#3
0
void CUnitScript::Spin(int piece, int axis, float speed, float accel)
{
	struct AnimInfo *ai;
	ai = FindAnim(ASpin, piece, axis);

	//If we are already spinning, we may have to decelerate to the new speed
	if (ai) {
		ai->dest = speed;
		if (accel > 0) {
			ai->accel = accel;
		}
		else {
			//Go there instantly. Or have a defaul accel?
			ai->speed = speed;
			ai->accel = 0;
		}
	}
	else {
		//No accel means we start at desired speed instantly
		if (accel <= 0)
			AddAnim(ASpin, piece, axis, speed, speed, 0);
		else
			AddAnim(ASpin, piece, axis, 0, speed, accel);
	}
}
void CCobInstance::Spin(int piece, int axis, int speed, int accel)
{
	struct AnimInfo *ai;
	ai = FindAnim(ASpin, piece, axis);

	//logOutput.Print("Spin called %d %d %d %d", piece, axis, speed, accel);

	//Test of default acceleration
	if (accel == 0)
		accel = 1000;

	//If we are already spinning, we may have to decelerate to the new speed
	if (ai) {
		ai->dest = speed;		
		if (accel > 0) {
			if (ai->speed > ai->dest)
				ai->accel = -accel;
			else
				ai->accel = accel;
		}
		else {
			//Go there instantly. Or have a defaul accel?
			ai->speed = speed;
			ai->accel = 0;
		}
	}
	else {
		//No accel means we start at desired speed instantly
		if (accel == 0)
			AddAnim(ASpin, piece, axis, speed, speed, accel);			
		else
			AddAnim(ASpin, piece, axis, 0, speed, accel);
	}
}
//Overwrites old information. This means that threads blocking on turn completion
//will now wait for this new turn instead. Not sure if this is the expected behaviour
//Other option would be to kill them. Or perhaps unblock them.
void CCobInstance::AddAnim(AnimType type, int piece, int axis, int speed, int dest, int accel, bool interpolated)
{
	struct AnimInfo *ai;

	//Turns override spins.. Not sure about the other way around? If so the system should probably be redesigned
	//to only have two types of anims.. turns and moves, with spin as a bool
	if (type == ATurn)
		RemoveAnim(ASpin, piece, axis);
	if (type == ASpin)
		RemoveAnim(ATurn, piece, axis);

	ai = FindAnim(type, piece, axis);
	if (!ai) {
		ai = new struct AnimInfo;
		ai->type = type;
		ai->piece = piece;
		ai->axis = axis;
		anims.push_back(ai);

		//If we were not animating before, inform the engine of this so it can schedule us
		if (anims.size() == 1) {
			GCobEngine.AddInstance(this);
		}

		// Check to make sure the piece exists
		if (piece >= pieces.size()) {
			logOutput.Print("Invalid piece in anim %d (%d)", piece, pieces.size());
		}
	}
	ai->speed = speed;
	ai->dest = dest;
	ai->accel = accel;
	ai->interpolated = interpolated;
}
示例#6
0
void AnimationComponent::PlayAnim(const std::string& name, int flags)
{
	unsigned int anim = FindAnim(name);
	if (anim != NOT_FOUND)
	{
		PlayAnim(anim, flags);
	}
}
示例#7
0
//Returns true if there was an animation to listen to
bool CUnitScript::AddAnimListener(AnimType type, int piece, int axis, IAnimListener *listener)
{
	struct AnimInfo *ai;
	ai = FindAnim(type, piece, axis);
	if (ai) {
		ai->listeners.push_back(listener);
		return true;
	}
	else
		return false;
}
int CCobInstance::AddMoveListener(int piece, int axis, CCobThread *listener)
{
	struct AnimInfo *ai;
	ai = FindAnim(AMove, piece, axis);
	if (ai) {
		ai->listeners.push_back(listener);
		return 1;
	}
	else 
		return 0;	
}
void CCobInstance::StopSpin(int piece, int axis, int decel)
{
	struct AnimInfo *ai;
	ai = FindAnim(ASpin, piece, axis);
	if (!ai)
		return;

	if (decel == 0) {
		RemoveAnim(ASpin, piece, axis);
	}
	else
		AddAnim(ASpin, piece, axis, ai->speed, 0, -decel);
}
示例#10
0
void CUnitScript::StopSpin(int piece, int axis, float decel)
{
	std::list<AnimInfo*>::iterator animInfoIt = FindAnim(ASpin, piece, axis);

	if (decel <= 0) {
		RemoveAnim(ASpin, animInfoIt);
	} else {
		if (animInfoIt == anims[ASpin].end())
			return;

		AnimInfo* ai = *animInfoIt;
		ai->dest = 0;
		ai->accel = decel;
	}
}
示例#11
0
void CUnitScript::StopSpin(int piece, int axis, float decel)
{
	if (decel <= 0) {
		RemoveAnim(ASpin, piece, axis);
	}
	else {
		struct AnimInfo *ai;
		ai = FindAnim(ASpin, piece, axis);
		if (!ai)
			return;

		ai->dest = 0;
		ai->accel = decel;
	}
}
示例#12
0
//Overwrites old information. This means that threads blocking on turn completion
//will now wait for this new turn instead. Not sure if this is the expected behaviour
//Other option would be to kill them. Or perhaps unblock them.
void CUnitScript::AddAnim(AnimType type, int piece, int axis, float speed, float dest, float accel, bool interpolated)
{
	if (!PieceExists(piece)) {
		ShowScriptError("Invalid piecenumber");
		return;
	}

	float destf;
	if (type == AMove) {
		destf = pieces[piece]->original->offset[axis] + dest;
	} else {
		destf = dest;
		if (type == ATurn) {
			ClampRad(&destf);
		}
	}

	struct AnimInfo *ai;

	//Turns override spins.. Not sure about the other way around? If so the system should probably be redesigned
	//to only have two types of anims.. turns and moves, with spin as a bool
	//todo: optimize, atm RemoveAnim and FindAnim search twice through all anims
	if (type == ATurn)
		RemoveAnim(ASpin, piece, axis);
	if (type == ASpin)
		RemoveAnim(ATurn, piece, axis);

	ai = FindAnim(type, piece, axis);
	if (!ai) {
		// If we were not animating before, inform the engine of this so it can schedule us
		if (anims.empty()) {
			GUnitScriptEngine.AddInstance(this);
		}

		ai = new struct AnimInfo;
		ai->type = type;
		ai->piece = piece;
		ai->axis = axis;
		anims.push_back(ai);
	}

	ai->dest  = destf;
	ai->speed = speed;
	ai->accel = accel;
	ai->interpolated = interpolated;
}
void CCobInstance::MoveSmooth(int piece, int axis, int destination, int delta, int deltaTime)
{
	//Make sure we do not overwrite animations of non-interpolated origin
	AnimInfo *ai = FindAnim(AMove, piece, axis);
	if (ai) {
		if (!ai->interpolated) {
			//logOutput.Print("Anim move overwrite");
			MoveNow(piece, axis, destination);
			return;
		}
	}

	int cur = pieces[piece].coords[axis];
	int dist = abs(destination - cur);
	int timeFactor = (1000 * 1000) / (deltaTime * deltaTime);
	int speed = (dist * timeFactor) / delta;

	//logOutput.Print("Move %d got %d %d", cur, destination, speed);

	Move(piece, axis, speed, destination, true);
}
void CCobInstance::TurnSmooth(int piece, int axis, int destination, int delta, int deltaTime)
{
	AnimInfo *ai = FindAnim(ATurn, piece, axis);
	if (ai) {
		if (!ai->interpolated) {
			//logOutput.Print("Anim turn overwrite");
			TurnNow(piece, axis, destination);
			return;
		}
	}

	int cur = pieces[piece].rot[axis];
	short int dist = destination - cur;
	int timeFactor = (1000 * 1000) / (deltaTime * deltaTime);
	dist = abs(dist);
	int speed = (dist * timeFactor) / delta;

	//logOutput.Print("Turnx %d:%d cur %d got %d %d dist %d", piece, axis, cur, destination, speed, dist);

	Turn(piece, axis, speed, destination, true);
}
示例#15
0
void CUnitScript::TurnSmooth(int piece, int axis, float destination, int delta, int deltaTime)
{
	if (!PieceExists(piece)) {
		ShowScriptError("Invalid piecenumber");
		return;
	}

	AnimInfo *ai = FindAnim(ATurn, piece, axis);
	if (ai) {
		if (!ai->interpolated) {
			TurnNow(piece, axis, destination);
			return;
		}
	}

	// not sure the ClampRad() call is necessary here
	float cur = ClampRad(pieces[piece]->rot[axis]);
	float dist = streflop::fabsf(destination - cur);
	int timeFactor = (1000 * 1000) / (deltaTime * deltaTime);
	float speed = (dist * timeFactor) / delta;

	Turn(piece, axis, speed, destination, true);
}
示例#16
0
void CUnitScript::MoveSmooth(int piece, int axis, float destination, int delta, int deltaTime)
{
	if (!PieceExists(piece)) {
		ShowScriptError("Invalid piecenumber");
		return;
	}

	//Make sure we do not overwrite animations of non-interpolated origin
	AnimInfo *ai = FindAnim(AMove, piece, axis);
	if (ai) {
		if (!ai->interpolated) {
			MoveNow(piece, axis, destination);
			return;
		}
	}

	float cur = pieces[piece]->pos[axis] - pieces[piece]->original->offset[axis];
	float dist = streflop::fabsf(destination - cur);
	int timeFactor = (1000 * 1000) / (deltaTime * deltaTime);
	float speed = (dist * timeFactor) / delta;

	Move(piece, axis, speed, destination, true);
}
示例#17
0
//Overwrites old information. This means that threads blocking on turn completion
//will now wait for this new turn instead. Not sure if this is the expected behaviour
//Other option would be to kill them. Or perhaps unblock them.
void CUnitScript::AddAnim(AnimType type, int piece, int axis, float speed, float dest, float accel)
{
	if (!PieceExists(piece)) {
		ShowScriptError("Invalid piecenumber");
		return;
	}

	float destf = 0.0f;

	if (type == AMove) {
		destf = pieces[piece]->original->offset[axis] + dest;
	} else {
		destf = dest;
		if (type == ATurn) {
			ClampRad(&destf);
		}
	}

	std::list<AnimInfo*>::iterator animInfoIt;
	AnimInfo* ai = NULL;
	AnimType overrideType = ANone;

	// first find an animation of a type we override
	// Turns override spins.. Not sure about the other way around? If so
	// the system should probably be redesigned to only have two types of
	// anims (turns and moves), with spin as a bool
	switch (type) {
		case ATurn: {
			overrideType = ASpin;
			animInfoIt = FindAnim(overrideType, piece, axis);
		} break;
		case ASpin: {
			overrideType = ATurn;
			animInfoIt = FindAnim(overrideType, piece, axis);
		} break;
		case AMove: {
			// ensure we never remove an animation of this type
			overrideType = AMove;
			animInfoIt = anims[overrideType].end();
		} break;
		default: {
		} break;
	}

	if (animInfoIt != anims[overrideType].end())
		RemoveAnim(overrideType, animInfoIt);

	// now find an animation of our own type
	animInfoIt = FindAnim(type, piece, axis);

	if (animInfoIt == anims[type].end()) {
		// If we were not animating before, inform the engine of this so it can schedule us
		// FIXME: this could be done in a cleaner way
		if (!HaveAnimations()) {
			GUnitScriptEngine.AddInstance(this);
		}

		ai = new AnimInfo();
		ai->type = type;
		ai->piece = piece;
		ai->axis = axis;
		anims[type].push_back(ai);
	} else {
		ai = *animInfoIt;
	}

	ai->dest  = destf;
	ai->speed = speed;
	ai->accel = accel;
	ai->done = false;
}