예제 #1
0
GENESISAPI void GENESISCC gePhysicsJoint_SetLocationBInWorldSpace(gePhysicsJoint* pPhysjnt, const geVec3d* pLoc)
{
	assert(pPhysjnt != NULL);
	assert(pLoc != NULL);
	
	geVec3d_Copy(pLoc, &pPhysjnt->locationBInWorldSpace);
}
예제 #2
0
파일: Camera.c 프로젝트: 5432935/genesis3d
//========================================================================================
//	geCamera_ScreenPointToWorld
//========================================================================================
GENESISAPI void GENESISCC geCamera_ScreenPointToWorld (	const geCamera	*Camera,
														int32			 ScreenX,
														int32			 ScreenY,
														geVec3d			*Vector)
// Takes a screen X and Y pair, and a camera and generates a vector pointing
// in the direction from the camera position to the screen point.
{
	geVec3d In,Left,Up;
	geVec3d ScaledIn,ScaledLeft,ScaledUp ;
	geFloat	XCenter ;
	geFloat	YCenter ;
	geFloat	Scale ;
	const geXForm3d *pM;

	pM = &(Camera->TransposeXForm);
	XCenter = Camera->XCenter ;
	YCenter = Camera->YCenter ;
	Scale   = Camera->Scale ;

	geXForm3d_GetIn( pM, &In ) ;
	geXForm3d_GetLeft( pM, &Left ) ;
	geXForm3d_GetUp( pM, &Up ) ;
	
	geVec3d_Scale(&In,   Scale, &ScaledIn);
	geVec3d_Scale(&Left, XCenter - ((geFloat)ScreenX), &ScaledLeft );
	geVec3d_Scale(&Up,   YCenter - ((geFloat)ScreenY), &ScaledUp   );

	geVec3d_Copy(&ScaledIn, Vector);
	geVec3d_Add(Vector,		&ScaledLeft,	Vector );
	geVec3d_Add(Vector,		&ScaledUp,		Vector );
	geVec3d_Normalize(Vector);
}
예제 #3
0
GENESISAPI void GENESISCC gePhysicsJoint_GetLocationAInWorldSpace(const gePhysicsJoint* pPhysjnt, geVec3d* pLoc)
{
	assert(pPhysjnt != NULL);
	assert(pLoc != NULL);
	
	geVec3d_Copy(&pPhysjnt->locationAInWorldSpace, pLoc);
}
예제 #4
0
/* ------------------------------------------------------------------------------------ */
int CRain::Create(Rain *R)
{
	int effect = -1;
    Spray Sp;

    // clear out spray data
    memset(&Sp, 0, sizeof(Sp));

    // get bitmap for use as texture
    // rain/a_rain are default bitmap names
    Sp.Texture = TPool_Bitmap("rain.bmp", "a_rain.bmp", R->BmpName, R->AlphaName);

    // setup spray data
    Sp.MinScale		= 0.5f;
    Sp.MaxScale		= 1.5f;
	Sp.ShowAlways	= GE_TRUE;
    Sp.Rate			= (1.1f - R->Severity)*0.1f;
    geVec3d_Copy(&(R->Gravity), &(Sp.Gravity));

	// set source position
    geVec3d_Copy(&(R->origin), &(Sp.Source));
	Sp.SourceVariance	= (int)(R->Radius*0.5f);
    Sp.MinUnitLife		= R->DropLife;
    Sp.MaxUnitLife		= R->DropLife;

	// set destination position
    geVec3d_AddScaled(&(Sp.Source), &(Sp.Gravity), Sp.MinUnitLife, &(Sp.Dest));
    Sp.DestVariance = (int)(R->Radius*0.5f);

	memcpy(&(Sp.ColorMin), &(R->ColorMin), sizeof(Sp.ColorMin));
    memcpy(&(Sp.ColorMax), &(R->ColorMax), sizeof(Sp.ColorMax));

	Sp.ColorMin.a = Sp.ColorMax.a = 255.0f;

	Sp.UseWind = R->UseWind;

	effect = CCD->EffectManager()->Item_Add(EFF_SPRAY, (void*)&Sp);
	return effect;
}
예제 #5
0
// changed QD 12/15/05 - changed 2nd argument from geVec3d to const geVec3d&
int CAutoDoors::PlaySound(geSound_Def *theSound, const geVec3d &Origin, bool SoundLoop)
{
	if(!theSound)
		return -1;

	Snd Sound;

	memset(&Sound, 0, sizeof(Sound));
    geVec3d_Copy(&Origin, &(Sound.Pos));
    Sound.Min = CCD->GetAudibleRadius();
	Sound.Loop = SoundLoop;
	Sound.SoundDef = theSound;
	int index = CCD->EffectManager()->Item_Add(EFF_SND, (void*)&Sound);

	if(SoundLoop)
		return index;

	return -1;
}
예제 #6
0
GENESISAPI gePhysicsJoint * GENESISCC gePhysicsJoint_Create(gePhysicsJoint_Kind Kind, const geVec3d *Location, 
	geFloat assemblyRate, gePhysicsObject *PS1, gePhysicsObject *PS2, geFloat physicsScale)
{
	gePhysicsJoint*	pPhysjnt;
	geVec3d		POLocation;
	geVec3d		physicsSpaceLocation;

	pPhysjnt = NULL;
	pPhysjnt = GE_RAM_ALLOCATE_STRUCT(gePhysicsJoint);
	if (pPhysjnt == NULL)
	{
		return NULL;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// make sure the joint makes sense

	pPhysjnt->Type = Kind;
	pPhysjnt->assemblyRate = assemblyRate * JOINT_ASSEMBLY_RATE_MULTIPLIER;
	pPhysjnt->Object1 = PS1;
	pPhysjnt->Object2 = PS2;

	geVec3d_Scale(Location, physicsScale, &physicsSpaceLocation);

	switch (Kind)
	{
		case JT_WORLD:
			if (PS1 == NULL)
			{
				/*
				GenVSI_Error(VSI, 
					GE_FALSE, 
					"Joint_Spawn: World joint needs non-NULL gePhysicsObject1 field.\n");
				*/
				return NULL;
			}
			#if 0
			if (pJoint->Next == pJoint)
			{
				/*
				GenVSI_Error(VSI, 
					GE_FALSE, 
					"Joint_Spawn: Next field points to parent.\n");
				*/
				return NULL;
			}
			#endif
			
			gePhysicsObject_GetLocation(PS1, &POLocation, 0);

			geVec3d_Subtract(&physicsSpaceLocation,
				&POLocation,
				&pPhysjnt->locationA);
			geVec3d_Copy(&physicsSpaceLocation, &pPhysjnt->locationB);
			break;

		case JT_SPHERICAL:
			if (PS1 == NULL || PS2 == NULL)
			{
				/*
				GenVSI_Error(VSI, 
					GE_FALSE, 
					"Joint_Spawn: Spherical joint needs 2 non-NULL gePhysicsObjects.\n");
				*/
				return NULL;
			}
			#if 0
			if (pJoint->Next == pJoint)
			{
				/*
				GenVSI_Error(VSI, 
					GE_FALSE, 
					"Joint_Spawn: Next field points to parent.\n");
				*/
			}
			#endif
			if (PS1 == PS2)
			{
				/*
				GenVSI_Error(VSI, 
					GE_FALSE, 
					"Joint_Spawn: Spherical joint: need 2 distinct gePhysicsObjects.\n");
				*/
				return NULL;
			}

			gePhysicsObject_GetLocation(PS1, &POLocation, 0);
			geVec3d_Subtract(&physicsSpaceLocation,
				&POLocation,
				&pPhysjnt->locationA);

			gePhysicsObject_GetLocation(PS2, &POLocation, 0);
			geVec3d_Subtract(&physicsSpaceLocation,
				&POLocation,
				&pPhysjnt->locationB);
			break;

		default:
			/*
			GenVSI_Error(VSI, 
				GE_FALSE, 
				"Joint_Spawn: unsupported joint type %d.\n", ij->jointType);
			*/
			return NULL;
	}

	return pPhysjnt;
}
/* ------------------------------------------------------------------------------------ */
void CCameraManager::DoIsoTracking()
{
	geXForm3d theViewPoint;
	geVec3d Pos;
	GE_Collision Collision;
	geVec3d Front, Back;
	geVec3d Direction;
	geFloat CurrentDistance;
	geExtBox ActorExtBox;
	geFloat ActorScale;
	geVec3d Orient;
	geFloat x;

	CCD->ActorManager()->GetScale(theActor, &ActorScale);		// Get actor scale
	CCD->ActorManager()->GetBoundingBox(theActor, &ActorExtBox);
	CurrentDistance = m_defaultdistance * ActorScale;

	geVec3d ActorPosition, ActorRotation;
	CCD->ActorManager()->GetPosition(theActor, &ActorPosition);
	ActorPosition.Y += CameraOffsetTranslation.Y;
	CCD->ActorManager()->GetRotation(theActor, &ActorRotation);
	ActorRotation.X = 0.0f;

// changed QD 12/15/05
	//geXForm3d_SetIdentity(&theViewPoint);
	//geXForm3d_RotateZ(&theViewPoint, CameraOffsetRotation.Z);
	geXForm3d_SetZRotation(&theViewPoint, CameraOffsetRotation.Z);
// end change
	geXForm3d_RotateX(&theViewPoint, CameraOffsetRotation.X+GE_PIOVER180*(m_cameraX));
	geXForm3d_RotateY(&theViewPoint, CameraOffsetRotation.Y+GE_PIOVER180*(m_cameraY));
	geXForm3d_Translate(&theViewPoint, ActorPosition.X, ActorPosition.Y, ActorPosition.Z);

	Pos = theViewPoint.Translation;
	geXForm3d_GetIn(&theViewPoint, &Direction);
	geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
// changed QD 12/15/05
	// geVec3d_AddScaled(&Pos, &Direction, 0.0f, &Front);
	geVec3d_Copy(&Pos, &Front);
// end change

	if(IsoCollFlag)
	{
		if(geWorld_Collision(CCD->World(), &CameraExtBox.Min, &CameraExtBox.Max, &Front,
		&Back, /*GE_VISIBLE_CONTENTS*/GE_CONTENTS_SOLID_CLIP, GE_COLLIDE_ALL, 0, NULL, NULL, &Collision))
		{
// changed QD 01/2004
			// can't be negative (sqrt)
			// CurrentDistance = (geFloat)fabs(geVec3d_DistanceBetween(&Collision.Impact, &Front));
			// if(CurrentDistance < 0.0f)
			//	CurrentDistance = 0.0f;
			CurrentDistance = geVec3d_DistanceBetween(&Collision.Impact, &Front);
// end change

			if(CurrentDistance > (m_defaultdistance*ActorScale))
				CurrentDistance = m_defaultdistance*ActorScale;

			geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
		}

// changed QD 01/2004
		if(CCD->Meshes()->CollisionCheck(&CameraExtBox.Min, &CameraExtBox.Max, Front, Back, &Collision))
		{
			geFloat CurrentDistance2 = geVec3d_DistanceBetween(&Collision.Impact, &Front);

			if(CurrentDistance2 > (m_defaultdistance*ActorScale))
				CurrentDistance2 = m_defaultdistance*ActorScale;

			if(CurrentDistance2<CurrentDistance)
			{
				CurrentDistance = CurrentDistance2;
				geVec3d_AddScaled(&Pos, &Direction, CurrentDistance2, &Back);
			}
		}
// end change
	}

	m_currentdistance = CurrentDistance/ActorScale;

	if(IsoCollFlag)
	{
		geFloat fAlpha = 255.0f;

		if(CurrentDistance < (40.0f*ActorScale))
		{
			fAlpha = (10.0f*((CurrentDistance-((geFloat)fabs(ActorExtBox.Min.Z)+1.0f))/ActorScale))+30.0f;

			if(fAlpha < (15.0f*ActorScale))
				fAlpha = 0.0f;

			if(fAlpha > 255.0f)
				fAlpha = 255.0f;
		}

		CCD->ActorManager()->SetAlpha(theActor, fAlpha);			// Adjust actor alpha
	}

	geVec3d_Subtract( &Pos, &Back, &Orient );

	// protect from Div by Zero
	if(CurrentDistance > 0.0f)
	{
		x = Orient.X;
		// changed QD 12/15/05
		// Orient.X = GE_PI*0.5f - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.X = GE_PIOVER2 - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.Y = (geFloat)atan2(x, Orient.Z) + GE_PI;
		Orient.Z = 0.0f;	// roll is zero - always!!?

	}

	Rotation = Orient;										// Set camera orientation
	Translation = Back;										// Set camera translation

	return;
}
/* ------------------------------------------------------------------------------------ */
void CCameraManager::DoThirdPersonTracking()
{
	geXForm3d theViewPoint;
	geVec3d Pos;
	GE_Collision Collision;
	geVec3d Front, Back;
	geVec3d Direction;
	geFloat CurrentDistance;
	geExtBox ActorExtBox;
	geFloat ActorScale;
	geVec3d Orient;
	geFloat x;
// changed QD 01/2004
	geFloat PlayerScale = CCD->Player()->GetScale();
// end change

	CCD->ActorManager()->GetScale(theActor, &ActorScale);		// Get actor scale
	CCD->ActorManager()->GetBoundingBox(theActor, &ActorExtBox);
	CurrentDistance = m_defaultdistance * ActorScale;

	geVec3d ActorPosition, ActorRotation;
	CCD->ActorManager()->GetPosition(theActor, &ActorPosition);
	ActorPosition.Y += CameraOffsetTranslation.Y;
	CCD->ActorManager()->GetRotation(theActor, &ActorRotation);
// Start Nov2003DCS
	geVec3d_Add(&ActorRotation, &CameraOffsetRotation, &ActorRotation);
// End Nov2003DCS
	ActorRotation.X = 0.0f;

// changed QD 12/15/05
	//geXForm3d_SetIdentity(&theViewPoint);
	//geXForm3d_RotateZ(&theViewPoint, ActorRotation.Z+CameraOffsetRotation.Z);
	geXForm3d_SetZRotation(&theViewPoint, ActorRotation.Z+CameraOffsetRotation.Z);
// end change
	geXForm3d_RotateX(&theViewPoint, ActorRotation.X+CameraOffsetRotation.X+GE_PIOVER180*(m_cameraX));
	geXForm3d_RotateY(&theViewPoint, ActorRotation.Y+CameraOffsetRotation.Y+GE_PIOVER180*(m_cameraY));
	geXForm3d_Translate(&theViewPoint, ActorPosition.X, ActorPosition.Y, ActorPosition.Z);

	Pos = theViewPoint.Translation;
	geXForm3d_GetIn(&theViewPoint, &Direction);
	geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
// changed QD 12/15/05
	// geVec3d_AddScaled(&Pos, &Direction, 0.0f, &Front);
	geVec3d_Copy(&Pos, &Front);
// end change

	if(geWorld_Collision(CCD->World(), &CameraExtBox.Min, &CameraExtBox.Max, &Front,
		&Back, /*GE_VISIBLE_CONTENTS*/GE_CONTENTS_SOLID_CLIP, GE_COLLIDE_ALL, 0, NULL, NULL, &Collision))
    {
// changed QD 01/2004
		// can't be negative (sqrt!)
		// CurrentDistance = (geFloat)fabs(geVec3d_DistanceBetween(&Collision.Impact, &Front));
		// if(CurrentDistance < 0.0f)
		//	CurrentDistance = 0.0f;
		CurrentDistance = geVec3d_DistanceBetween(&Collision.Impact, &Front);
// end change

		if(CurrentDistance > (m_defaultdistance*ActorScale))
			CurrentDistance = m_defaultdistance*ActorScale;

		geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
	}

// changed QD 01/2004
	geVec3d_AddScaled(&Pos, &Direction, playermindistance*ActorScale, &Front);

	if(CCD->Meshes()->CollisionCheck(&CameraExtBox.Min, &CameraExtBox.Max, Front, Back, &Collision))
	{
// changed QD distance can't be negative
	//	geFloat CurrentDistance2 = (geFloat)fabs(geVec3d_DistanceBetween(&Collision.Impact, &Front));//-4.0f;
		geFloat CurrentDistance2 = geVec3d_DistanceBetween(&Collision.Impact, &Front);

		CurrentDistance2 += playermindistance*ActorScale;

		if(theActor == CCD->Player()->GetActor())
		{
			if(CurrentDistance2 < (playermindistance*ActorScale))
				CurrentDistance2 = playermindistance*ActorScale;
			if(CurrentDistance2 > (playermaxdistance*ActorScale))
				CurrentDistance2 = playermaxdistance*ActorScale;
		}
		else
		{
			if(CurrentDistance2 > (m_defaultdistance*ActorScale))
				CurrentDistance2 = m_defaultdistance*ActorScale;
		}

		if(CurrentDistance2 < CurrentDistance)
		{
			CurrentDistance = CurrentDistance2;
			geVec3d_AddScaled(&Pos, &Direction, CurrentDistance2, &Back);
		}
	}
// end change

	m_currentdistance = CurrentDistance/ActorScale;

	// Ok, here's the implementation of Ralph Deane's too-cool
	// ..third-person Actor Fading code. As the camera approaches
	// ..the player avatar, the AVATAR IS FADED OUT until finally
	// ..it's rendering is shut down. This is one Way Cool Effect.
	// 03/22/2000 eaa3 Added Ralph Deane's scaling fixes.

	geFloat fAlpha = 255.0f;

	if(CurrentDistance < (40.0f*ActorScale))
	{
		fAlpha = (10.0f*((CurrentDistance-((geFloat)fabs(ActorExtBox.Min.Z)+1.0f))/ActorScale))+30.0f;

		if(fAlpha < (15.0f*ActorScale))
			fAlpha = 0.0f;

		if(fAlpha > 255.0f)
			fAlpha = 255.0f;
	}

	CCD->ActorManager()->SetAlpha(theActor, fAlpha);			// Adjust actor alpha

	geVec3d_Subtract( &Pos, &Back, &Orient );

	// protect from Div by Zero
	if(CurrentDistance > 0.0f)
	{
		x = Orient.X;
		// changed QD 12/15/05
		// Orient.X = (geFloat)( GE_PI*0.5 ) - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.X = GE_PIOVER2 - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.Y = (geFloat)atan2(x, Orient.Z) + GE_PI;
		Orient.Z = 0.0f;	// roll is zero - always!!?
	}

	Rotation = Orient;										// Set camera orientation
	Translation = Back;										// Set camera translation

	return;
}
/* ------------------------------------------------------------------------------------ */
bool ControllerObject::method(const skString& methodName, skRValueArray& arguments,
							  skRValue& returnValue, skExecutableContext& ctxt)
{
	char  string1[128], string2[128];
	float float1;
	bool  bool1;
//	int   int1;

	string1[0] = '\0';
	string2[0] = '\0';

	if(IS_METHOD(methodName, "SetPlatformTargetTime"))
	{
		PARMCHECK(2);
		strcpy(string1, arguments[0].str());
		float1 = arguments[1].floatValue();
		MovingPlatform *pEntity;
		CCD->Platforms()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->SetTargetTime(pEntity->Model, float1);
		return true;
	}
	else if(IS_METHOD(methodName, "GetPlatformTargetTime"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		MovingPlatform *pEntity;
		CCD->Platforms()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->GetTargetTime(pEntity->Model, &float1);
		returnValue = (float)float1;
		return true;
	}
	else if(IS_METHOD(methodName, "GetPlatformCurrentTime"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		MovingPlatform *pEntity;
		CCD->Platforms()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->GetModelCurrentTime(pEntity->Model, &float1);
		returnValue = (float)float1;
		return true;
	}
	else if(IS_METHOD(methodName, "PlatformCollision"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		MovingPlatform *pEntity;
		CCD->Platforms()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->ModelInCollision(pEntity->Model, &bool1);
		returnValue = (bool)bool1;
		return true;
	}

	if(IS_METHOD(methodName, "SetDoorTargetTime"))
	{
		PARMCHECK(2);
		strcpy(string1, arguments[0].str());
		float1 = arguments[1].floatValue();
		Door *pEntity;
		CCD->Doors()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->SetTargetTime(pEntity->Model, float1);
		return true;
	}
	else if(IS_METHOD(methodName, "GetDoorTargetTime"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		Door *pEntity;
		CCD->Doors()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->GetTargetTime(pEntity->Model, &float1);
		returnValue = (float)float1;
		return true;
	}
	else if(IS_METHOD(methodName, "GetDoorCurrentTime"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		Door *pEntity;
		CCD->Doors()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->GetModelCurrentTime(pEntity->Model, &float1);
		returnValue = (float)float1;
		return true;
	}
	else if(IS_METHOD(methodName, "DoorCollision"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		Door *pEntity;
		CCD->Doors()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->ModelInCollision(pEntity->Model, &bool1);
		returnValue = (bool)bool1;
		return true;
	}
	else if(IS_METHOD(methodName, "ShowWallDecal"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		CCD->WallDecals()->SetProgrammedTrigger(string1, GE_TRUE);
		return true;
	}
	else if(IS_METHOD(methodName, "HideWallDecal"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		CCD->WallDecals()->SetProgrammedTrigger(string1, GE_FALSE);
		return true;
	}
	else if(IS_METHOD(methodName, "SetWallDecalBitmap"))
	{
		PARMCHECK(2);
		strcpy(string1, arguments[0].str());
		int bmnum = arguments[1].intValue();
		CCD->WallDecals()->SetCurrentBitmap(string1, bmnum);
		return true;
	}
	else if(IS_METHOD(methodName, "ActivateTrigger"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		CCD->Triggers()->HandleTriggerEvent(string1);
		return true;
	}
	else if(IS_METHOD(methodName, "GetEventState"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		returnValue = (bool)GetTriggerState(string1);
		return true;
	}
	else if(IS_METHOD(methodName, "SetEventState"))
	{
		PARMCHECK(2);
		strcpy(string1, arguments[0].str());
		bool flag = arguments[1].boolValue();
		CCD->Pawns()->AddEvent(string1, flag);
		return true;
	}
	else if(IS_METHOD(methodName, "Start3DAudioSource"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		CCD->Audio3D()->SetProgrammedTrigger(string1, GE_TRUE);
		return true;
	}
	else if(IS_METHOD(methodName, "Stop3DAudioSource"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		CCD->Audio3D()->SetProgrammedTrigger(string1, GE_FALSE);
		return true;
	}
	else if(IS_METHOD(methodName, "Get3DAudioSourceState"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		bool state = CCD->Audio3D()->IsPlaying(string1);
		returnValue = (bool)state;
		return true;
	}
	else if(IS_METHOD(methodName, "PlaySound"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());

		if(!EffectC_IsStringNull(string1))
		{
			geVec3d Position = CCD->Player()->Position();
			Snd Sound;

			memset(&Sound, 0, sizeof(Sound));
			geVec3d_Copy(&Position, &(Sound.Pos));
			Sound.Min = CCD->GetAudibleRadius();

			if(arguments.entries() == 2)
				Sound.Min = arguments[1].floatValue();

			Sound.Loop = GE_FALSE;
			Sound.SoundDef = SPool_Sound(string1);

			if(Sound.SoundDef != NULL)
				CCD->EffectManager()->Item_Add(EFF_SND, (void*)&Sound);
		}

		return true;
	}
// changed Nout 12/15/05
	// ShowText(Nr, EntityName, Animation, TextString, FontNr, TextSound, ScreenOffsetX, ScreenOffsetY, Align, Alpha);
	// Shows a TextMessage on the screen, attached to a Pawn or Player
	// Align can be Right, Left or Centre. If left open, Right is used.
	// The text can include a # to print it in multiple lines
	else if(IS_METHOD(methodName, "ShowText"))
	{
		int Nr = arguments[0].intValue();

		if(Nr < 0 || Nr >= MAXTEXT)
			return true;

		if(arguments.entries() > 1)
		{
			strcpy(CCD->Pawns()->TextMessage[Nr].EntityName, arguments[1].str());
			strcpy(CCD->Pawns()->TextMessage[Nr].AnimName, arguments[2].str());
			//strcpy(CCD->Pawns()->TextMessage[Nr].TextString, arguments[3].str());
			CCD->Pawns()->TextMessage[Nr].TextString = arguments[3].str();
			Replace(CCD->Pawns()->TextMessage[Nr].TextString, "<Player>", CCD->Player()->GetPlayerName());

			CCD->Pawns()->TextMessage[Nr].FontNr = arguments[4].intValue();
			strcpy(CCD->Pawns()->TextMessage[Nr].TextSound, arguments[5].str());
			CCD->Pawns()->TextMessage[Nr].ScreenOffsetX = arguments[6].intValue();
			CCD->Pawns()->TextMessage[Nr].ScreenOffsetY = arguments[7].intValue();
			strncpy(&(CCD->Pawns()->TextMessage[Nr].Alignment), arguments[8].str(), 1);
			CCD->Pawns()->TextMessage[Nr].Alpha = arguments[9].floatValue();
			CCD->Pawns()->TextMessage[Nr].ShowText = true;
		}
		else
			CCD->Pawns()->TextMessage[Nr].ShowText = false;

		return true;
	}
	else if(IS_METHOD(methodName, "RemoveText"))
	{
		int Nr = arguments[0].intValue();

		if(Nr < 0 || Nr >= MAXTEXT)
			return true;

		CCD->Pawns()->TextMessage[Nr].ShowText = false;

		return true;
	}
	// SetPlatformSpeed(PlatformName, Speed)
	else if(IS_METHOD(methodName, "SetPlatformSpeed"))
	{
		PARMCHECK(2);
		MovingPlatform *pEntity;

		strcpy(string1, arguments[0].str());
		float1 = arguments[1].floatValue();

		CCD->Platforms()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->SetAnimationSpeed(pEntity->Model, float1);

		return true;
	}
	// SetDoorSpeed(DoorName, Speed)
	else if(IS_METHOD(methodName, "SetDoorSpeed"))
	{
		PARMCHECK(2);
		Door *pEntity;

		strcpy(string1, arguments[0].str());
		float1 = arguments[1].floatValue();

		CCD->Doors()->LocateEntity(string1, (void**)&pEntity);
		CCD->ModelManager()->SetAnimationSpeed(pEntity->Model, float1);

		return true;
	}
	// move immediately a platform to a given timeposition
	// SetPlatformTimeNow(PlatformName, KeyFrame)
	else if(IS_METHOD(methodName, "SetPlatformToTargetTime"))
	{
		PARMCHECK(2);
		MovingPlatform *pEntity;

		strcpy(string1, arguments[0].str());
		float1 = arguments[1].floatValue();

		CCD->Platforms()->LocateEntity(string1, (void**)&pEntity);
        CCD->ModelManager()->SetToTargetTime(pEntity->Model, float1);

		return true;
	}
	// move immediately a door to a given timeposition
	// SetDoorTimeNow(DoorName, KeyFrame)
	else if(IS_METHOD(methodName, "SetDoorToTargetTime"))
	{
		PARMCHECK(2);
		Door *pEntity;

		strcpy(string1, arguments[0].str());
		float1 = arguments[1].floatValue();

		CCD->Doors()->LocateEntity(string1, (void**)&pEntity);
        CCD->ModelManager()->SetToTargetTime(pEntity->Model, float1);

		return true;
	}
	// SetFlag(FlagNr, BooleanValue)
	else if(IS_METHOD(methodName, "SetFlag"))
	{
		int int1 = arguments[0].intValue();

		if(int1 >= MAXFLAGS)
			return true;

		bool1 = arguments[1].boolValue();
		CCD->Pawns()->SetPawnFlag(int1, bool1);

		return true;
	}
	// Boolean:GetFlag(FlagNr)
	else if(IS_METHOD(methodName, "GetFlag"))
	{
		int int1 = arguments[0].intValue();

		if(int1 >= MAXFLAGS)
		{
			returnValue = false;
			return true;
		}

		returnValue = CCD->Pawns()->GetPawnFlag(int1);

		return true;
	}
	// Distance:PlatformDistance(PlatformName, EntityName, IgnoreHeight)
	// Returns the distance form the platform center to the origin of an Entity
	// Apart from Pawns also 2 special Entity names are supported: "Player" and "Camera"
	else if(IS_METHOD(methodName, "PlatformDistance"))
	{
		PARMCHECK(3);
		geVec3d PlatformPos, EntityPos;
		MovingPlatform *pEntity;

		strcpy(string1, arguments[0].str());

		if(CCD->Platforms()->LocateEntity(string1, (void**)&pEntity) == RGF_SUCCESS)
		{
			CCD->ModelManager()->GetPosition(pEntity->Model, &PlatformPos);
			strcpy(string1, arguments[1].str());

			if(!stricmp(string1, "Player"))
				EntityPos = CCD->Player()->Position();
			else if(!stricmp(string1, "Camera"))
				CCD->CameraManager()->GetPosition(&EntityPos);
			else
				CCD->ActorManager()->GetPosition(CCD->ActorManager()->GetByEntityName(string1), &EntityPos);

			if(arguments.entries() > 2)
				if(arguments[2].boolValue())
					PlatformPos.Y = EntityPos.Y;

   			returnValue = geVec3d_DistanceBetween(&PlatformPos, &EntityPos);
		}
		else
			returnValue = 0;

		return true;
	}
	// Distance:DoorDistance(DoorName, EntityName, IgnoreHeight)
	// Gives the distance from the platform centre to the origin of an Entity
	// Apart from Pawns also 2 special Entity names are supported: "Player" and "Camera"
	else if (IS_METHOD(methodName, "DoorDistance"))
	{
		PARMCHECK(3);
		geVec3d DoorPos, EntityPos;
		Door *pEntity;

		strcpy(string1, arguments[0].str());

		if(CCD->Doors()->LocateEntity(string1, (void**)&pEntity) == RGF_SUCCESS)
		{
			CCD->ModelManager()->GetPosition(pEntity->Model, &DoorPos);
			strcpy(string1, arguments[1].str());

			if(!stricmp(string1, "Player"))
				EntityPos = CCD->Player()->Position();
			else if(!stricmp(string1, "Camera"))
				CCD->CameraManager()->GetPosition(&EntityPos);
			else
				CCD->ActorManager()->GetPosition(CCD->ActorManager()->GetByEntityName(string1), &EntityPos);

			if(arguments.entries() > 2)
				if(arguments[2].boolValue())
					DoorPos.Y = EntityPos.Y;
				if(arguments.entries() > 2)
			returnValue = geVec3d_DistanceBetween(&DoorPos, &EntityPos);
		}
		else
			returnValue = 0;

		return true;
	}
// end change
	else if(IS_METHOD(methodName, "Console"))
	{
		PARMCHECK(1);
		console = arguments[0].boolValue();

		if(console)
		{
			ConsoleHeader = (char*)malloc(128);
			*ConsoleHeader = '\0';
			ConsoleError = (char*)malloc(128);
			*ConsoleError = '\0';

			for(int i=0; i<DEBUGLINES; i++)
			{
				ConsoleDebug[i] = (char*)malloc(64);
				*ConsoleDebug[i] = '\0';
			}
		}
		else
		{
			if(ConsoleHeader)
				free(ConsoleHeader);

			if(ConsoleError)
				free(ConsoleError);

			for(int i=0; i<DEBUGLINES; i++)
			{
				if(ConsoleDebug[i])
					free(ConsoleDebug[i]);
			}
		}

		return true;
	}
	else if(IS_METHOD(methodName, "debug"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());

		if(console)
		{
			int index = -1;
			int i;

			for(i=0; i<DEBUGLINES; i++)
			{
				if(EffectC_IsStringNull(ConsoleDebug[i]))
				{
					index = i;
					break;
				}
			}

			if(index != -1)
			{
				strcpy(ConsoleDebug[index], string1);
			}
			else
			{
				for(i=1; i<DEBUGLINES; i++)
				{
					strcpy(ConsoleDebug[i-1], ConsoleDebug[i]);
				}

				strcpy(ConsoleDebug[DEBUGLINES-1], string1);
			}
		}

		return true;
	}
	else if(IS_METHOD(methodName, "random"))
	{
		PARMCHECK(2);
		int param1 = arguments[0].intValue();
		int param3 = arguments[1].intValue();

		if(param1 < param3)
			returnValue = EffectC_rand(param1, param3);
		else
			returnValue = EffectC_rand(param3, param1);

		return true;
	}
	else if(IS_METHOD(methodName, "StringCopy"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		returnValue = skString(string1);
		return true;
	}
	else if(IS_METHOD(methodName, "LeftCopy"))
	{
		PARMCHECK(2);

		int temp = arguments[1].intValue();
		// changed QD 07/15/06
		/*
		char* cstemp="";
		strncpy(cstemp,arguments[0].str(),temp);
		cstemp[temp]='\0';
		returnValue = skString(cstemp);
		*/
		temp = (temp<127)?temp:127;
		strncpy(string1, arguments[0].str(), temp);
		string1[temp] = 0;
		returnValue = skString(string1);
		// end change
		return true;
	}
	else if(IS_METHOD(methodName, "Integer"))
	{
		PARMCHECK(1);
		int temp = arguments[0].intValue();
		returnValue = (int)temp;
		return true;
	}
	else if(IS_METHOD(methodName, "ModifyAttribute")) // changed QD 12/15/05
	{
		PARMCHECK(2);
		strcpy(string1, arguments[0].str());
// changed QD 12/15/05
		//CPersistentAttributes *theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
		CPersistentAttributes *theInv;

		if(arguments.entries() > 2)
		{
			strcpy(string2, arguments[2].str());

			if(!stricmp(string2, "Player"))
				theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
			else
				theInv = CCD->ActorManager()->Inventory(CCD->ActorManager()->GetByEntityName(string2));
		}
		else
			theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
// end change
		returnValue = (int)theInv->Modify(string1, arguments[1].intValue());
		return true;
	}
	else if(IS_METHOD(methodName, "GetAttribute"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
// changed QD 12/15/05
		//CPersistentAttributes *theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
		CPersistentAttributes *theInv;

		if(arguments.entries() > 1)
		{
			strcpy(string2, arguments[1].str());

			if(!stricmp(string2, "Player"))
				theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
			else
				theInv = CCD->ActorManager()->Inventory(CCD->ActorManager()->GetByEntityName(string2));
		}
		else
			theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
// end change
		returnValue = (int)theInv->Value(string1);
		return true;
	}

	else if(IS_METHOD(methodName, "SetAttribute"))
	{
		PARMCHECK(2);
		strcpy(string1, arguments[0].str());
// changed QD 12/15/05
		//CPersistentAttributes *theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
		CPersistentAttributes *theInv;

		if(arguments.entries() > 2)
		{
			strcpy(string2, arguments[2].str());

			if(!stricmp(string2, "Player"))
				theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
			else
				theInv = CCD->ActorManager()->Inventory(CCD->ActorManager()->GetByEntityName(string2));
		}
		else
			theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
// end change
		returnValue = (int)theInv->Set(string1, arguments[1].intValue());
		return true;
	}
// changed QD 12/15/05
	else if(IS_METHOD(methodName, "AddAttribute"))
	{
		// USAGE:	AddAttribute(char *Attribute)
		//			AddAttribute(char *Attribute, char *EntityName)

		// changed QD 07/15/06 - add optional arguments
		//			AddAttribute(char *Attribute, int LowValue, int HighValue)
		//			AddAttribute(char *Attribute, int LowValue, int HighValue, char *EntityName)

		PARMCHECK(1);
		strcpy(string1, arguments[0].str());

		CPersistentAttributes *theInv;

		if(arguments.entries() == 2 || arguments.entries() == 4)
		{
			strcpy(string2, arguments[arguments.entries()-1].str());

			if(!stricmp(string2, "Player"))
				theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
			else
				theInv = CCD->ActorManager()->Inventory(CCD->ActorManager()->GetByEntityName(string2));
		}
		else
			theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());

		returnValue = (int)theInv->Add(string1);

		if(arguments.entries() > 2)
		{
			theInv->SetValueLimits(string1, arguments[1].intValue(), arguments[2].intValue());
		}
		// end change QD 07/15/06

		return true;
	}
// end change
// changed QD 07/15/06
	else if(IS_METHOD(methodName, "SetAttributeValueLimits"))
	{
		// USAGE:	SetAttributeValueLimits(char* Attribute, int LowValue, int HighValue),
		//			SetAttributeValueLimits(char* Attribute, int LowValue, int HighValue, char* EntityName)

		PARMCHECK(3);
		strcpy(string1, arguments[0].str());

		CPersistentAttributes *theInv;

		if(arguments.entries() > 3)
		{
			strcpy(string2, arguments[3].str());

			if(!stricmp(string2, "Player"))
				theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());
			else
				theInv = CCD->ActorManager()->Inventory(CCD->ActorManager()->GetByEntityName(string2));
		}
		else
			theInv = CCD->ActorManager()->Inventory(CCD->Player()->GetActor());

		theInv->SetValueLimits(string1, arguments[1].intValue(), arguments[2].intValue());

		return true;
	}
	else if(IS_METHOD(methodName, "RightCopy"))
	{
		int length;
		int temp = arguments[1].intValue();
		temp = (temp<127)?temp:127;
		strncpy(string1, arguments[0].str(), 127);
		string1[127] = 0;
		length = strlen(string1);

		strncpy(string2, &string1[length-temp], temp);
		string2[temp] = 0;
		returnValue = skString(string2);
		return true;
	}
	else if(IS_METHOD(methodName, "sin"))
	{
		PARMCHECK(1);
		returnValue = (float)sin((double)arguments[0].floatValue());

		return true;
	}
	else if(IS_METHOD(methodName, "cos"))
	{
		PARMCHECK(1);
		returnValue = (float)cos((double)arguments[0].floatValue());

		return true;
	}
	else if(IS_METHOD(methodName, "tan"))
	{
		PARMCHECK(1);
		returnValue = (float)tan((double)arguments[0].floatValue());

		return true;
	}
// end change QD 07/15/06
// changed QD 02/01/07
	else if(IS_METHOD(methodName, "asin"))
	{
		PARMCHECK(1);
		returnValue = (float)asin((double)arguments[0].floatValue());

		return true;
	}
	else if(IS_METHOD(methodName, "acos"))
	{
		PARMCHECK(1);
		returnValue = (float)acos((double)arguments[0].floatValue());

		return true;
	}
	else if(IS_METHOD(methodName, "atan"))
	{
		PARMCHECK(1);
		returnValue = (float)atan((double)arguments[0].floatValue());

		return true;
	}
// end change
	else if(IS_METHOD(methodName, "SetPlayerWeapon"))
	{
		PARMCHECK(1);
		int temp = arguments[0].intValue();
		CCD->Weapons()->SetWeapon(temp);
		return true;
	}
	else if(IS_METHOD(methodName, "SetUseItem"))
	{
		PARMCHECK(1);
		strcpy(string1, arguments[0].str());
		CCD->Player()->SetUseAttribute(string1);
		CCD->HUD()->ActivateElement(string1, true);
		return true;
	}
// changed RF071A
	else if(IS_METHOD(methodName, "IsKeyDown"))
	{
		PARMCHECK(1);
		int temp = arguments[0].intValue();
		returnValue = false;

		if(CCD->Input()->GetKeyCheck(temp) == true)
			returnValue = true;

		return true;
	}
// changed QD 12/15/05
	else if(IS_METHOD(methodName, "SetFixedCameraPosition"))
	{
		// USAGE: SetFixedCameraPosition(PosX, PosY, PosZ)
		PARMCHECK(3);

		geVec3d Pos;
		Pos.X = arguments[0].floatValue();
		Pos.Y = arguments[1].floatValue();
		Pos.Z = arguments[2].floatValue();
		CCD->FixedCameras()->SetPosition(Pos);

		return true;
	}
	else if(IS_METHOD(methodName, "SetFixedCameraRotation"))
	{
		// USAGE: SetFixedCameraRotation(RotX, RotY, RotZ)
		PARMCHECK(3);

		geVec3d Rot;
		Rot.X = GE_PIOVER180*arguments[0].floatValue();
		Rot.Y = GE_PIOVER180*arguments[1].floatValue();
		Rot.Z = GE_PIOVER180*arguments[2].floatValue();
		CCD->FixedCameras()->SetRotation(Rot);

		return true;
	}
	else if(IS_METHOD(methodName, "SetFixedCameraFOV"))
	{
		// USAGE: SetFixedCameraFOV(float FOV)
		PARMCHECK(1);

		CCD->FixedCameras()->SetFOV(arguments[0].floatValue());

		return true;
	}
	else if(IS_METHOD(methodName, "MoveFixedCamera"))
	{
		// USAGE: MoveFixedCamera(PosX, PosY, PosZ)
		PARMCHECK(3);

		geVec3d Pos;
		Pos.X = arguments[0].floatValue();
		Pos.Y = arguments[1].floatValue();
		Pos.Z = arguments[2].floatValue();
		CCD->FixedCameras()->Move(Pos);

		return true;
	}
	else if(IS_METHOD(methodName, "RotateFixedCamera"))
	{
		// USAGE: RotateFixedCamera(RotX, RotY, RotZ)
		PARMCHECK(3);

		geVec3d Rot;
		Rot.X = GE_PIOVER180*arguments[0].floatValue();
		Rot.Y = GE_PIOVER180*arguments[1].floatValue();
		Rot.Z = GE_PIOVER180*arguments[2].floatValue();
		CCD->FixedCameras()->Rotate(Rot);

		return true;
	}
// end change
	else
	{
		return skScriptedExecutable::method(methodName, arguments, returnValue, ctxt);
	}
}
예제 #10
0
/* ------------------------------------------------------------------------------------ */
void CRain::Tick(geFloat dwTicks)
{
	geEntity_EntitySet *pSet;
	geEntity *pEntity;
	int i;
	Spray Sp;

	pSet = geWorld_GetEntitySet(CCD->World(), "Rain");

	if(!pSet)
		return;

	for(pEntity=geEntity_EntitySetGetNextEntity(pSet, NULL); pEntity;
		pEntity=geEntity_EntitySetGetNextEntity(pSet, pEntity))
	{
		Rain *R = (Rain*)geEntity_GetUserData(pEntity);

		if(!EffectC_IsStringNull(R->TriggerName))
		{
			if(GetTriggerState(R->TriggerName))
			{
				if(R->active == GE_FALSE)
				{
					for(i=0; i<R->EffectCount; i++)
						R->EffectList[i] = Create(R);

					R->active = GE_TRUE;
				}
			}
			else
			{
				if(R->active == GE_TRUE)
				{
					for(i=0; i<R->EffectCount; i++)
						CCD->EffectManager()->Item_Delete(EFF_SPRAY, R->EffectList[i]);

					R->active = GE_FALSE;
				}
			}
		}
		else
		{
			if(R->active == GE_FALSE)
			{
				for(i=0; i<R->EffectCount; i++)
					R->EffectList[i] = Create(R);

				R->active = GE_TRUE;
			}
		}

		if(R->active == GE_TRUE)
		{
			R->origin = R->OriginOffset;

			if(SetOriginOffset(R->EntityName, R->BoneName, R->Model, &(R->origin)))
			{
	  			geVec3d_Copy(&(R->origin), &(Sp.Source));
				geVec3d_AddScaled(&(Sp.Source), &(Sp.Gravity), Sp.MinUnitLife, &(Sp.Dest));

				// adjust position
				for(i=0; i<R->EffectCount; i++)
					CCD->EffectManager()->Item_Modify(EFF_SPRAY, R->EffectList[i], (void *)&Sp, SPRAY_SOURCE | SPRAY_ACTUALDEST);
			}
	    }
	}
}
예제 #11
0
/* ------------------------------------------------------------------------------------ */
void ActorParticle_SystemAddParticle(ActorParticle_System	*ps,
									 char					*ActorName,
									 geVec3d				Position,
									 geVec3d				BaseRotation,
									 geVec3d				RotationSpeed,
									 GE_RGBA				FillColor,
									 GE_RGBA				AmbientColor,
									 // changed QD 07/21/04
									 geBoolean				AmbientLightFromFloor,
									 // end change
									 float					Alpha,
									 float					AlphaRate,
									 geFloat				Time,
									 const geVec3d			*Velocity,
									 geFloat				Scale,
									 bool					Gravity,
									 geBoolean				Bounce,
									 geBoolean				Solid,
									 bool					EnvironmentMapping,
									 bool					AllMaterial,
									 float					PercentMapping,
									 float					PercentMaterial)
{
	// locals
	ActorParticle *ptcl;

	// create a new particle
	ptcl = ActorCreateParticle(ps, ActorName, Position, BaseRotation);

	if(!ptcl)
		return;

	// setup velocity
	if(Velocity != (const geVec3d*)NULL)
	{
		geVec3d_Copy(Velocity, &(ptcl->ptclVelocity));
		ptcl->ptclFlags |= PARTICLE_HASVELOCITY;
	}

	// setup remaining data
//	changed QD 07/21/04
//	CCD->ActorManager()->SetActorDynamicLighting(ptcl->Actor, FillColor, AmbientColor);
	CCD->ActorManager()->SetActorDynamicLighting(ptcl->Actor, FillColor, AmbientColor, AmbientLightFromFloor);
// end change

	if(EnvironmentMapping)
		SetEnvironmentMapping(ptcl->Actor, true, AllMaterial, PercentMapping, PercentMaterial);

	CCD->ActorManager()->SetScale(ptcl->Actor, Scale);

	ptcl->ptclTime = Time;
	ptcl->ptclTotalTime = Time;

	CCD->ActorManager()->SetAlpha(ptcl->Actor, Alpha);

	ptcl->Alpha = Alpha;
	ptcl->AlphaRate = AlphaRate;
	ptcl->Bounce = Bounce;
	ptcl->RotationSpeed = RotationSpeed;

	CCD->ActorManager()->GetBoundingBox(ptcl->Actor, &ptcl->theBox);
	CCD->ActorManager()->SetBoxChange(ptcl->Actor, false);

	if(!Solid)
		CCD->ActorManager()->SetNoCollide(ptcl->Actor);

	CCD->ActorManager()->SetHideRadar(ptcl->Actor, true);

	if(Gravity)
		CCD->ActorManager()->SetGravity(ptcl->Actor, CCD->Player()->GetGravity());
}
예제 #12
0
/* ------------------------------------------------------------------------------------ */
void Particle_SystemAddParticle(Particle_System		*ps,
								geBitmap			*Texture,
								const GE_LVertex	*Vert,
								const geVec3d		*AnchorPoint,
								geFloat				Time,
								const geVec3d		*Velocity,
								geFloat				Scale,
								const geVec3d		*Gravity,
								geBoolean			Bounce,
								geBoolean			UseWind)
{
	// locals
	Particle *ptcl;

	// create a new particle
	ptcl = CreateParticle(ps, Texture, Vert);
	if(!ptcl)
	{
		return;
	}

	// setup gravity
	if(Gravity != (const geVec3d*)NULL)
	{
		geVec3d_Copy(Gravity, &(ptcl->Gravity));
		ptcl->ptclFlags |= PARTICLE_HASGRAVITY;
	}

	// setup velocity
	if(Velocity != (const geVec3d*)NULL)
	{
		geVec3d_Copy(Velocity, &(ptcl->ptclVelocity));
		ptcl->ptclFlags |= PARTICLE_HASVELOCITY;
	}

	//setup wind
	if(UseWind == GE_TRUE)
	{
		ptcl->ptclFlags |= PARTICLE_HASWIND;
	}

	// setup the anchor point
	if(AnchorPoint != (const geVec3d*)NULL)
	{
		geVec3d_Copy(AnchorPoint, &(ptcl->CurrentAnchorPoint));
		ptcl->AnchorPoint = AnchorPoint;
	}

	// setup remaining data
	ptcl->Scale = Scale;
	ptcl->ptclTime = Time;
	ptcl->ptclTotalTime = Time;
	ptcl->Alpha = Vert->a;
	ptcl->Bounce = Bounce;

	// add the poly to the world
#ifdef	POLYQ
	ptcl->ptclPoly = geWorld_AddPoly(ps->psWorld,
									&(ptcl->ptclVertex),
									1,
									ptcl->ptclTexture,
									GE_TEXTURED_POINT,
									PARTICLE_RENDERSTYLE,
									ptcl->Scale);
#endif
}
예제 #13
0
/* ------------------------------------------------------------------------------------ */
void Particle_SystemFrame(Particle_System *ps, geFloat DeltaTime)
{
	geVec3d	AnchorDelta;

	// the quick fix to the particle no-draw problem
	ps->psQuantumSeconds = DeltaTime;

	{
		Particle *ptcl;

		ptcl = ps->psParticles;

		while(ptcl)
		{
			ptcl->ptclTime -= ps->psQuantumSeconds;

			if(ptcl->ptclTime <= 0.0f)
			{
				Particle *temp;

				temp = ptcl->ptclNext;
				UnlinkParticle(ps, ptcl);
				DestroyParticle(ps, ptcl);
				ptcl = temp;
				continue;
			}
			else
			{
				// locals
				geVec3d	DeltaPos = {0.0f, 0.0f, 0.0f};

				// apply velocity
				if(ptcl->ptclFlags & PARTICLE_HASVELOCITY)
				{
					geVec3d_Scale(&(ptcl->ptclVelocity), ps->psQuantumSeconds, &DeltaPos);
				}

				// apply gravity
				if(ptcl->ptclFlags & PARTICLE_HASGRAVITY)
				{
					// locals
					geVec3d	Gravity;

					// make gravity vector
					geVec3d_Scale(&(ptcl->Gravity), ps->psQuantumSeconds, &Gravity);

					// apply gravity to built in velocity and DeltaPos
					geVec3d_Add(&(ptcl->ptclVelocity), &Gravity, &(ptcl->ptclVelocity));
					geVec3d_Add(&DeltaPos, &Gravity, &DeltaPos);
				}

				//apply wind
				if(ptcl->ptclFlags & PARTICLE_HASWIND)
				{
					geVec3d Wind = CCD->Player()->GetWind();

					//make wind vector
					geVec3d_Scale(&Wind, ps->psQuantumSeconds, &Wind);

					//add wind to delta pos
					geVec3d_Add(&DeltaPos, &Wind, &DeltaPos);
				}

				// apply DeltaPos to particle position
				if((ptcl->ptclFlags & PARTICLE_HASVELOCITY) || (ptcl->ptclFlags & PARTICLE_HASGRAVITY) || (ptcl->ptclFlags & PARTICLE_HASWIND))
				{
					geVec3d temppos, temppos1;
					GE_Collision Collision;
					geVec3d_Copy((geVec3d*)&(ptcl->ptclVertex.X), &temppos);
					geVec3d_Add(&temppos, &DeltaPos, &temppos1);

					if(ptcl->Bounce)
					{
						float totalTravelled = 1.0f;// keeps track of fraction of path travelled (1.0=complete)
						float margin = 0.001f;		// margin to be satisfied with (1.0 - margin == 1.0)
						int loopCounter = 0;		// safety valve for endless collisions in tight corners
						const int maxLoops = 10;

						while(geWorld_Collision(CCD->World(), NULL, NULL, &temppos,
							&temppos1, GE_VISIBLE_CONTENTS, GE_COLLIDE_ALL, 0, NULL, NULL, &Collision))
						{
							float ratio ;
							float elasticity = 1.3f ;
							float friction = 0.9f ; // loses (1 minus friction) of speed

							CollisionCalcRatio(Collision, temppos, temppos1, &ratio);
							CollisionCalcImpactPoint(Collision, temppos, temppos1, 1.0f, ratio, &temppos1);
							CollisionCalcVelocityImpact(Collision, ptcl->ptclVelocity, elasticity,
														friction, &(ptcl->ptclVelocity));

							if(ratio >= 0)
								totalTravelled += (1.0f - totalTravelled) * ratio ;

							if(totalTravelled >= 1.0f - margin)
								break ;

							if(++loopCounter >= maxLoops) // safety check
								break ;
						}
					}
					else
					{
						if(geWorld_Collision(CCD->World(), NULL, NULL, &temppos,
							&temppos1, GE_VISIBLE_CONTENTS, GE_COLLIDE_ALL, 0, NULL, NULL, &Collision))
						{
							Particle *temp;
							temp = ptcl->ptclNext;
							UnlinkParticle(ps, ptcl);
							DestroyParticle(ps, ptcl);
							ptcl = temp;
							continue;
						}
					}

					geVec3d_Copy(&temppos1, (geVec3d *)&(ptcl->ptclVertex.X));
				}

				// make the particle follow its anchor point if it has one
				if(ptcl->AnchorPoint != (const geVec3d*)NULL)
				{
					geVec3d_Subtract(ptcl->AnchorPoint, &(ptcl->CurrentAnchorPoint), &AnchorDelta);
					geVec3d_Add((geVec3d*)&(ptcl->ptclVertex.X), &AnchorDelta, (geVec3d*)&(ptcl->ptclVertex.X));
					geVec3d_Copy(ptcl->AnchorPoint, &(ptcl->CurrentAnchorPoint));
				}
			}

#ifndef	POLYQ
			// set particle alpha
			ptcl->ptclVertex.a = ptcl->Alpha * (ptcl->ptclTime / ptcl->ptclTotalTime);

			geWorld_AddPolyOnce(ps->psWorld,
								&(ptcl->ptclVertex),
								1,
								ptcl->ptclTexture,
								GE_TEXTURED_POINT,
								PARTICLE_RENDERSTYLE,
								ptcl->Scale);
#else
			// set particle alpha
			ptcl->ptclVertex.a = ptcl->Alpha * (ptcl->ptclTime / ptcl->ptclTotalTime);

			if(ptcl->ptclPoly)
				gePoly_SetLVertex(ptcl->ptclPoly, 0, &(ptcl->ptclVertex));
#endif

			ptcl = ptcl->ptclNext;
		}

		DeltaTime -= QUANTUMSIZE;
	}

	ps->psLastTime += DeltaTime;
}