GENESISAPI void GENESISCC gePhysicsJoint_SetLocationBInWorldSpace(gePhysicsJoint* pPhysjnt, const geVec3d* pLoc) { assert(pPhysjnt != NULL); assert(pLoc != NULL); geVec3d_Copy(pLoc, &pPhysjnt->locationBInWorldSpace); }
//======================================================================================== // 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); }
GENESISAPI void GENESISCC gePhysicsJoint_GetLocationAInWorldSpace(const gePhysicsJoint* pPhysjnt, geVec3d* pLoc) { assert(pPhysjnt != NULL); assert(pLoc != NULL); geVec3d_Copy(&pPhysjnt->locationAInWorldSpace, pLoc); }
/* ------------------------------------------------------------------------------------ */ 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; }
// 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; }
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); } }
/* ------------------------------------------------------------------------------------ */ 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); } } } }
/* ------------------------------------------------------------------------------------ */ 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()); }
/* ------------------------------------------------------------------------------------ */ 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 }
/* ------------------------------------------------------------------------------------ */ 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; }