General Question How to make multiple vessels function in same scenario?

asbjos

tuanibrO
Addon Developer
Joined
Jun 22, 2011
Messages
696
Reaction score
259
Points
78
Location
This place called "home".
Hello!

I've coded a spaceprobe with animations with parents (solar arrays for example). It works fine when there's only one probe in the scenario, but when I have two or more, the animations don't work. See the picture.
Error.jpg


I understand (I hope) that it has something about private and public variables, but I can't find a solution. If the scenario contains several probes the animations work for the first probe which I animate, but the others after that have bugged animations. If the animations are activated for only one vessel at the time, it works.

The first mesh group (parent) of the animation performs well, but the children of the first mesh group don't work.

Here is the relevant code (the animation variables are at the end of the private section):
PHP:
class ChapmanInner1: public VESSEL3
{
public:
	ChapmanInner1 (OBJHANDLE hObj, int fmodel)
	: VESSEL3 (hObj, fmodel)
	{
		DefineAnimations();
	}
	// In the order which it appears in the code
	void clbkPostCreation();
	void clbkPreStep (double simt, double simdt, double mjd);
	bool clbkDrawHUD (int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad *skp);
	void clbkPostStep (double simt, double simdt, double mjd);
	void clbkSetClassCaps (FILEHANDLE cfg);
	void clbkLoadStateEx (FILEHANDLE scn, void *vs);
	void clbkSaveState (FILEHANDLE scn);
	int clbkConsumeBufferedKey (DWORD key, bool down, char *kstate);

	int ChapmanID; // For OrbiterSound

	// Variables and constants
	bool VesselDestroyed;
	bool MFD_Left_Is_On;
	bool MFD_Right_Is_On;
	bool ProbeErrorUsed;
	bool FuelErrorUsed;
	bool LOSCalloutUsed;
	int DamageModelActive;
	int Current_HUD_In_Use;
	int ActiveCamera; /*	0 = main camera (narrow-field camera)
							1 = antenna (Low-Gain Antenna)
							2 = camera following solar arrays (for rotating to the Sun)*/
	bool TimeAccWhileEngineOnAlert;
	double TimeAtAlert;
	double AlertErrorEnd;
	double TimeLeftBeforeErrorDissapears;

	bool for_array_used;
	bool CameraInside;
	bool laser_on;
	int laser_switch;
	double is_laser_on;

	DWORD ScreenWidth, ScreenHeight, ScreenColour;
	int TextX0, TextY0, LineSpacing;
	int ShowOnHUD;

	double AccelerationFactorWas;

	NOTEHANDLE YoureDeadBecause;
	bool HaveWrittenOnScreen;

	int WasRotatingInDirection;

private:
	PROPELLANT_HANDLE MainTank;
	PROPELLANT_HANDLE RCSTank;
	THRUSTER_HANDLE th_main, th_rcs[24], th_rcsgroup[4], laser;

	double MAIN_THRUST_LEVEL;

	double RCS_ATT_FORWARD_LEVEL;
	double RCS_ATT_BACK_LEVEL;
	double RCS_ATT_LEFT_LEVEL;
	double RCS_ATT_RIGHT_LEVEL;
	double RCS_ATT_UP_LEVEL;
	double RCS_ATT_DOWN_LEVEL;
	double RCS_ATT_PITCHUP_LEVEL;
	double RCS_ATT_PITCHDOWN_LEVEL;
	double RCS_ATT_YAWLEFT_LEVEL;
	double RCS_ATT_YAWRIGHT_LEVEL;
	double RCS_ATT_BANKLEFT_LEVEL;
	double RCS_ATT_BANKRIGHT_LEVEL;

	// Animations
	UINT RotateArray;
	UINT DeployArray;
	UINT DeployMagnetometer;

	double ArrayRotateProcess;
	double ArrayDeployProcess;
	double MagnetometerDeployProcess;

	ANIMATIONCOMPONENT_HANDLE 
		RotateArrayAnimation,

		DeployArrayAnimation1,
		DeployArrayAnimation2,
		DeployArrayAnimation3,
		DeployArrayAnimation4,
		DeployArrayAnimation5,
		DeployArrayAnimation6,
		DeployArrayAnimation7,
		DeployArrayAnimation8,
		DeployArrayAnimation9,
		DeployArrayAnimation10,
		DeployArrayAnimation11,
		DeployArrayAnimation12,
		DeployArrayAnimation13,
		DeployArrayAnimation14,
		DeployArrayAnimation15,
		DeployArrayAnimation16,

		DeployMagnetometerAnimation1,
		DeployMagnetometerAnimation2,
		DeployMagnetometerAnimation3;

	// 0 = stowed, 1 = deployed, 2 = stowing, 3 = deploying
	int ArrayRotateStatus;
	int ArrayDeployStatus;
	int MagnetometerDeployStatus;

	void DefineAnimations(void);
};

PHP:
void ChapmanInner1::DefineAnimations()
{
	// Animations
	static UINT MagnetometerDeployGroups1[1] = {226}; // participating groups
	static UINT MagnetometerDeployGroups2[2] = {133, 134}; // participating groups
	static UINT MagnetometerDeployGroups3[13] = {123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 224, 225, 267}; // participating groups

	static MGROUP_ROTATE MagnetometerDeploy1 (
		0,									// mesh index
		MagnetometerDeployGroups1, 1,		// group list and number of groups
		_V(0.38422557,0.8224564,-0.7292426),// rotation reference point
		_V(1, 0, 0),						// rotation axis
		(float)(-135*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE MagnetometerDeploy2 (
		0,									// mesh index
		MagnetometerDeployGroups2, 2,		// group list and number of groups
		_V(0.38422557,0.8228145,0.9239347),	// rotation reference point
		_V(1, 0, 0),						// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE MagnetometerDeploy3 (
		0,									// mesh index
		MagnetometerDeployGroups3, 13,		// group list and number of groups
		_V(0.38422557,0.8626972,0.9239347),	// rotation reference point
		_V(1, 0, 0),						// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	DeployMagnetometer = CreateAnimation(0);
	DeployMagnetometerAnimation1 = AddAnimationComponent (DeployMagnetometer, 0, 1, &MagnetometerDeploy1);
	DeployMagnetometerAnimation2 = AddAnimationComponent (DeployMagnetometer, 0, 1, &MagnetometerDeploy2, DeployMagnetometerAnimation1);
	DeployMagnetometerAnimation3 = AddAnimationComponent (DeployMagnetometer, 0, 1, &MagnetometerDeploy3, DeployMagnetometerAnimation2);

	// Solar array deploy/retract animation
	static UINT ArrayRotateGroups[2] = {86,90}; // participating groups
	
	static MGROUP_ROTATE ArrayRotate (
		0,								// mesh index
		ArrayRotateGroups, 2,			// group list and number of groups
		_V(0,-0.3313698,-0.1128273),	// rotation reference point
		_V(-1, 0, 0),					// rotation axis
		(float)(360*RAD)					// angular rotation range
	);

	RotateArray = CreateAnimation(0);
	RotateArrayAnimation = AddAnimationComponent (RotateArray, 0, 1, &ArrayRotate);

	// Array deploy groups (16 parts)
	static UINT ArrayDeployGroups1[1] = {91};
	static UINT ArrayDeployGroups2[3] = {92, 227, 293};
	static UINT ArrayDeployGroups3[2] = {15, 16};
	static UINT ArrayDeployGroups4[2] = {200, 290};
	static UINT ArrayDeployGroups5[2] = {17, 18};
	static UINT ArrayDeployGroups6[2] = {201, 291};
	static UINT ArrayDeployGroups7[2] = {19, 20};
	static UINT ArrayDeployGroups8[2] = {202, 292};
	static UINT ArrayDeployGroups9[1] = {87};
	static UINT ArrayDeployGroups10[3] = {88, 196, 286};
	static UINT ArrayDeployGroups11[2] = {9, 10};
	static UINT ArrayDeployGroups12[2] = {197, 287};
	static UINT ArrayDeployGroups13[2] = {11, 12};
	static UINT ArrayDeployGroups14[2] = {198, 288};
	static UINT ArrayDeployGroups15[2] = {13, 14};
	static UINT ArrayDeployGroups16[2] = {199, 289};

	static MGROUP_ROTATE ArrayDeploy1 (
		0,								// mesh index
		ArrayDeployGroups1, 1,			// group list and number of groups
		_V(-0.996575,-0.3313698,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy2 (
		0,								// mesh index
		ArrayDeployGroups2, 3,			// group list and number of groups
		_V(-1.032802,0.1059157,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-180*RAD)				// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy3 (
		0,								// mesh index
		ArrayDeployGroups3, 2,			// group list and number of groups
		_V(-1.04143,-0.592322,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy4 (
		0,								// mesh index
		ArrayDeployGroups4, 2,			// group list and number of groups
		_V(-1.058424,-0.592322,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy5 (
		0,								// mesh index
		ArrayDeployGroups5, 2,			// group list and number of groups
		_V(-1.065472,0.1077438,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-90*RAD)				// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy6 (
		0,								// mesh index
		ArrayDeployGroups6, 2,			// group list and number of groups
		_V(-1.082597,0.1077438,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-90*RAD)				// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy7 (
		0,								// mesh index
		ArrayDeployGroups7, 2,			// group list and number of groups
		_V(-1.089358,-0.592322,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy8 (
		0,								// mesh index
		ArrayDeployGroups8, 2,			// group list and number of groups
		_V(-1.106351,-0.592322,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy9 (
		0,								// mesh index
		ArrayDeployGroups9, 1,			// group list and number of groups
		_V(1.023222,-0.3313698,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy10 (
		0,								// mesh index
		ArrayDeployGroups10, 3,			// group list and number of groups
		_V(1.052366,0.1063364,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(180*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy11 (
		0,								// mesh index
		ArrayDeployGroups11, 2,			// group list and number of groups
		_V(1.066066,-0.5919511,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy12 (
		0,								// mesh index
		ArrayDeployGroups12, 2,			// group list and number of groups
		_V(1.08306,-0.5919511,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy13 (
		0,								// mesh index
		ArrayDeployGroups13, 2,			// group list and number of groups
		_V(1.090084,0.1081148,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy14 (
		0,								// mesh index
		ArrayDeployGroups14, 2,			// group list and number of groups
		_V(1.107209,0.1081148,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(90*RAD)					// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy15 (
		0,								// mesh index
		ArrayDeployGroups15, 2,			// group list and number of groups
		_V(1.113885,-0.5919511,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-90*RAD)				// angular rotation range
	);

	static MGROUP_ROTATE ArrayDeploy16 (
		0,								// mesh index
		ArrayDeployGroups16, 2,			// group list and number of groups
		_V(1.130921,-0.5919511,0),		// rotation reference point
		_V(0, 0, 1),					// rotation axis
		(float)(-90*RAD)				// angular rotation range
	);

	DeployArray = CreateAnimation(0);
	DeployArrayAnimation1 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy1, RotateArrayAnimation);
	DeployArrayAnimation2 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy2, DeployArrayAnimation1);
	DeployArrayAnimation3 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy3, DeployArrayAnimation2);
	DeployArrayAnimation4 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy4, DeployArrayAnimation3);
	DeployArrayAnimation5 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy5, DeployArrayAnimation4);
	DeployArrayAnimation6 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy6, DeployArrayAnimation5);
	DeployArrayAnimation7 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy7, DeployArrayAnimation6);
	DeployArrayAnimation8 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy8, DeployArrayAnimation7);
	DeployArrayAnimation9 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy9, RotateArrayAnimation);
	DeployArrayAnimation10 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy10, DeployArrayAnimation9);
	DeployArrayAnimation11 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy11, DeployArrayAnimation10);
	DeployArrayAnimation12 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy12, DeployArrayAnimation11);
	DeployArrayAnimation13 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy13, DeployArrayAnimation12);
	DeployArrayAnimation14 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy14, DeployArrayAnimation13);
	DeployArrayAnimation15 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy15, DeployArrayAnimation14);
	DeployArrayAnimation16 = AddAnimationComponent (DeployArray, 0, 1, &ArrayDeploy16, DeployArrayAnimation15);
}

Do anybody have a solution? Animations work on multiple vessels on the DG, so I guess there has to be a solution somewhere.
 

BruceJohnJennerLawso

Dread Lord of the Idiots
Addon Developer
Joined
Apr 14, 2012
Messages
2,585
Reaction score
0
Points
36
Do anybody have a solution? Animations work on multiple vessels on the DG, so I guess there has to be a solution somewhere.

... Thats, err, odd. :shifty:

Vessels should never experience problems like these.

Is there any sort of static variable in your vessel class? How sure are you that the problem is multiple instances of the same type, or could it maybe be something else?

Edit: yes, you do, but not where I expected them to be. Thats odd...

Just when you think you've seen every imaginable bug...

:hailprobe:

---------- Post added at 21:06 ---------- Previous post was at 21:02 ----------

Okay, dont quote me on this just yet, because I dont have my reference handy, but I believe static members of a C++ class are shared across all objects of that type. If that is the case, then maybe the animations are stuck in lockstep somehow?
 

meson800

Addon Developer
Addon Developer
Donator
Joined
Aug 6, 2011
Messages
405
Reaction score
2
Points
18
Yes, static members are shared across all objects of that type. Static variables inside member functions get weird though.
From http://stackoverflow.com/questions/15036633/static-variable-inside-member-function-of-base-class
Static variables declared in member functions will keep their value between function calls. There will be only one copy over all instances, and all accesses to indicator from different instances will affect the same indicator. This means indicator will only be initialized once.

I think the issue is probably in the following (and other calls of the type)
Code:
DeployArrayAnimation1 = AddAnimationComponent (DeployArray, 0, 1, [COLOR="Red"]&ArrayDeploy1[/COLOR], RotateArrayAnimation);
You return a pointer to the static variable, which is fine when there is one vessel. However, However, the next vessel created re-calls DefineAnimations, which re-creates all of the structs, which invalidate the pointer you passed.

There would be two solutions to this. The first would be to create another static variable, say
Code:
static bool hasDefinedAnimations
and make sure that DefineAnimations is only called once with the following
Code:
ChapmanInner1 (OBJHANDLE hObj, int fmodel)
    : VESSEL3 (hObj, fmodel)
    {
        [COLOR="Red"]if (hasDefinedAnimations)
        {[/COLOR]
          DefineAnimations();
         [COLOR="Red"] hasDefinedAnimations = true;
        }[/COLOR]
    }
Or, as I would do it, move the static variables into the private section of the class and just manipulate them in DefineAnimations. Although this does store a copy of the animations in every vessel, it is the most bug-free.
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
Top