/****************************************************** * fd: * Returns the doppler freqency, in Hz, between the * given satellite and the given point on the ground.*/ double fd(meta_parameters *meta,stateVector st,stateVector targ) { vector relPos,relVel; vecSub(st.vel,targ.vel,&relVel); vecSub(st.pos,targ.pos,&relPos); return -2*vecDot(relVel,relPos)/ (meta->sar->wavelength*vecMagnitude(relPos)); }
void getTriangleNormal(Vec tri[3], Vec norm) { Vec v0,v1; vecSub(tri[1], tri[0], v0); vecSub(tri[2], tri[0], v1); vecCrossProduct(v0, v1, norm); //VecCross(v0, v1, norm); vecNormalize(norm); }
int triangleEvaluateHalfSpace(const Triangle3DSetup &tri, VecRef xShuffle, VecRef yShuffle) { Vec DX12 = vec(tri.dx1); Vec DX23 = vec(tri.dx2); Vec DX31 = vec(tri.dx3); Vec DY12 = vec(tri.dy1); Vec DY23 = vec(tri.dy2); Vec DY31 = vec(tri.dy3); TriangleSetup s; triangleCalculateConstants(tri, s); Vec C1 = vec(s.c1); Vec C2 = vec(s.c2); Vec C3 = vec(s.c3); const Vec Zero = vec(0); const Vec p = vecCmpGT(vecSub(vecMadd(DX12, yShuffle, C1), vecMul(DY12, xShuffle)), Zero); const Vec q = vecCmpGT(vecSub(vecMadd(DX23, yShuffle, C2), vecMul(DY23, xShuffle)), Zero); const Vec r = vecCmpGT(vecSub(vecMadd(DX31, yShuffle, C3), vecMul(DY31, xShuffle)), Zero); #ifndef PLATFORM_PS3 const int a = vecMaskToInt(p); const int b = vecMaskToInt(q); const int c = vecMaskToInt(r); if(!a || !b || !c) { return FullyOutside; } else if(a == 0xf && b == 0xf && c == 0xf) { return FullyCovered; } else { return PartiallyInside; } #else vec_uint4 ones = (vec_uint4){0xffffffff,0xffffffff,0xffffffff,0xffffffff}; vec_uint4 zeros = (vec_uint4){0, 0, 0, 0}; if(vec_all_eq((vec_uint4)p, zeros) || vec_all_eq((vec_uint4)q, zeros) || vec_all_eq((vec_uint4)r, zeros)) { return FullyOutside; } else if(vec_all_eq((vec_uint4)p, ones) && vec_all_eq((vec_uint4)q, ones) && vec_all_eq((vec_uint4)r, ones)) { return FullyCovered; } else { return PartiallyInside; } #endif }
void updateAppendage(Scene* scene, int sceneIndex, cl_float3 p, cl_float3 q, cl_float3 w, float A, float B, int countA, int countB) { cl_float3 U; cl_float3 V; cl_float3 W; cl_float3 j; cl_float3 d; V = q; vecSub(V, p); float D = vecLength(V); float inverseD = 1.0f / D; vecScale(V, inverseD); W = w; vecNormalize(W); vecCross(U, V, W); float A2 = A*A; float y = 0.5f * inverseD * (A2 - B * B + D * D); double square = A2 - y*y; if (square < 0.0f) throw std::runtime_error("Unable to construct appendage"); float x = sqrtf(square); j = p; vecScaledAdd(j, x, U); vecScaledAdd(j, y, V); d = j; vecSub(d, p); vecScale(d, 1.0f / float(countA)); for (int i = 0; i <= countA; i++) { Sphere* sphere = &(scene->spheres[sceneIndex + i]); sphere->center = p; vecScaledAdd(sphere->center, float(i), d); vecScale(sphere->center, 0.1f); } d = j; vecSub(d, q); vecScale(d, 1.0f / float(countB)); for (int i = 0; i <= countA; i++) { Sphere* sphere = &(scene->spheres[sceneIndex + i + countA + 1]); sphere->center = q; vecScaledAdd(sphere->center, float(i), d); vecScale(sphere->center, 0.1f); } }
void SpecialCallBack(int key, int x, int y) { bool needRedisplay = true; switch (key) { case GLUT_KEY_LEFT: { animCamera = false; cl_float3 t = scene->cam.viewCenter; vecSub(t, scene->cam.eye); t.s[0] = t.s[0] * cosf(-ROTATE_STEP) - t.s[2] * sinf(-ROTATE_STEP); t.s[2] = t.s[0] * sinf(-ROTATE_STEP) + t.s[2] * cosf(-ROTATE_STEP); vecAdd(t, scene->cam.eye); camLookAt(scene->cam, t); break; } case GLUT_KEY_RIGHT: { animCamera = false; cl_float3 t = scene->cam.viewCenter; vecSub(t, scene->cam.eye); t.s[0] = t.s[0] * cosf(ROTATE_STEP) - t.s[2] * sinf(ROTATE_STEP); t.s[2] = t.s[0] * sinf(ROTATE_STEP) + t.s[2] * cosf(ROTATE_STEP); vecAdd(t, scene->cam.eye); camLookAt(scene->cam, t); break; } case GLUT_KEY_PAGE_UP: { animCamera = false; cl_float3 t; vecInit(t, 0.f, MOVE_STEP / 4.f, 0.f); vecAdd(scene->cam.viewCenter, t); camUpdate(scene->cam); break; } case GLUT_KEY_PAGE_DOWN: { animCamera = false; cl_float3 t; vecInit(t, 0.f, -MOVE_STEP / 4.f, 0.f); vecAdd(scene->cam.viewCenter, t); camUpdate(scene->cam); break; } default: needRedisplay = false; break; } if (needRedisplay) glutPostRedisplay(); }
lod *lodLevelGet(void *spaceObj, vector *camera, vector *ship) { real32 distance; SpaceObj *obj = (SpaceObj *)spaceObj; lodinfo *info = obj->staticinfo->staticheader.LOD; dbgAssert(info != NULL); //verify the LOD table exists vecSub(obj->cameraDistanceVector,*camera,*ship); obj->cameraDistanceSquared = distance = vecMagnitudeSquared(obj->cameraDistanceVector); #if LOD_SCALE_DEBUG if (lodDebugScaleFactor != 0.0f) { lodScaleFactor = lodDebugScaleFactor; } #endif if (distance > info->level[obj->currentLOD].bOff * lodScaleFactor) { //if drop a level of detail do { obj->currentLOD++; //go to lower level if (obj->currentLOD >= info->nLevels) { obj->currentLOD = info->nLevels-1; break; } } while (distance > info->level[obj->currentLOD].bOff * lodScaleFactor); } else { while (obj->currentLOD > 0 && distance < info->level[obj->currentLOD - 1].bOn * lodScaleFactor) { //if go higher level of detail obj->currentLOD--; //go to higher level } } dbgAssert(obj->currentLOD >= 0); dbgAssert(obj->currentLOD < info->nLevels); //verify we are within the available levels of detail #if LOD_PRINT_DISTANCE if (keyIsStuck(WKEY)) { keyClearSticky(WKEY); lodScaleFactor *= 0.99f; dbgMessagef("\nlodScaleFactor = %.3f", lodScaleFactor); } if (keyIsStuck(OKEY)) { keyClearSticky(OKEY); lodScaleFactor *= 1.01f; dbgMessagef("\nlodScaleFactor = %.3f", lodScaleFactor); } if (lodTuningMode) { obj->currentLOD = min(rndLOD, info->nLevels - 1); return(&info->level[min(rndLOD, info->nLevels - 1)]); } #endif return(&info->level[obj->currentLOD]); //return pointer to lod structure }
int camValidate(){ int answer = -1; Vec a; if(camera.resX == 0 || camera.resY == 0){ answer = 0; reportError("Camera resolution cannot be 0"); } if (camera.depth == 0.0 || camera.width == 0.0 || camera.height == 0.0){ answer = 0; reportError("Camera cannot be dimensionless"); } if (vecDot(&(camera.down), &(camera.down)) == 0.0){ answer = 0; reportError("Camera 'down' cannot be zero length"); } vecSub(&(camera.at), &(camera.lookAt), &a); if (vecDot(&a, &a) == 0.0){ answer = 0; reportError("Camera 'at' and 'look-at' cannot be co-incident"); } return answer; }
VectorTreeItemId BFBackupTree::GetTaskItems (wxTreeItemId idParent, bool bGoDeep /*= true*/) { VectorTreeItemId vec; wxTreeItemId idCurr; wxTreeItemIdValue idCookie; if (ItemHasChildren(idParent)) { for (idCurr = GetFirstChild(idParent, idCookie); idCurr.IsOk(); idCurr = GetNextChild(idParent, idCookie)) { if (ItemHasChildren(idCurr) == bGoDeep) { VectorTreeItemId vecSub(GetTaskItems(idCurr, true)); for (ItVectorTreeItemId it = vecSub.begin(); it != vecSub.end(); it++) { vec.push_back(*it); } } else { if (IsTask(idCurr)) vec.push_back(idCurr); } } } return vec; }
void getRotatePoint(Ship *ship, vector *point, real32 *distance) { Node *slavenode; Ship *slave; udword count; vector dist; dbgAssertOrIgnore(ship->flags & SOF_Slaveable); //ship should be slaveable dbgAssertOrIgnore(ship->slaveinfo->slaves.num >= 5); //need enough for a pie plate! slavenode = ship->slaveinfo->slaves.head; point->x = ship->posinfo.position.x; point->y = ship->posinfo.position.y; point->z = ship->posinfo.position.z; count = 0; while (count < 5) { slave = (Ship *) listGetStructOfNode(slavenode); vecAdd(*point, *point, slave->posinfo.position); slavenode = slavenode->next; count++; } point->x /= 6.0f; point->y /= 6.0f; point->z /= 6.0f; vecSub(dist,ship->posinfo.position, *point); *distance = vecMagnitudeSquared(dist); *distance = fsqrt(*distance); }
//fires the bursts for the ship bool doBurstFire(Ship *ship) { HeavyCorvetteSpec *spec = (HeavyCorvetteSpec *)ship->ShipSpecifics; GunInfo *gunInfo = ship->gunInfo; sdword numGuns = gunInfo->numGuns; //Gun *gun; sdword done; vector trajectory,heading; real32 range,one_over_range; SpaceObjRotImpTarg dummyTarg; vecSub(trajectory,spec->burstFireVector,ship->posinfo.position); range = vecMagnitudeSquared(trajectory); range = fsqrt(range); one_over_range = 1.0f/range; vecScalarMultiply(trajectory,trajectory,one_over_range); dummyTarg.objtype = OBJ_ShipType; dummyTarg.posinfo.position = spec->burstFireVector; dummyTarg.collInfo.collPosition = spec->burstFireVector; dummyTarg.currentLOD = ship->currentLOD; dummyTarg.collMyBlob = ship->collMyBlob; vecSet(dummyTarg.posinfo.velocity,0.0f,0.0f,0.0f); //track target even more precisely vecSub(heading,spec->burstFireVector,ship->posinfo.position); vecNormalize(&heading); aitrackHeadingWithFlags(ship,&heading,0.9999f,AITRACKHEADING_IGNOREUPVEC); //set special information that needs to be 'transmitted' //to the code in gunshoot. //fix later spec->bulletLifeTime = range*oneOverburstSpeed; bitSet(ship->specialFlags,SPECIAL_BurstFiring); done = gunShootGunsAtTarget(ship,&dummyTarg,0.0f,&trajectory); bitClear(ship->specialFlags,SPECIAL_BurstFiring); if(done == TRUE) { spec->cooldown = TRUE; spec->burstChargeState2 = burstCoolDownTime; } return done; }
/* Get_sep: Calculates the separation between two satellites along the satellite beam, in the normal- and parallel- to look direction. Inputs are: a state vector from scene 1, in GEI coordinates; the name of the ceos for image 2; the slant range and doppler of the center of the beam; and pointers to the output normal and parallel baselines. */ void get_sep(stateVector stVec1, meta_parameters *meta2, double range, double dop,double *Bn,double *Bp) { double lat,phi,earthRadius; vector target,up,relPos; vector upBeam,alongBeam,beamNormal; double t,timeDelta; stateVector stVec2; GEOLOCATE_REC *g; /*Target is the patch of ground at beam center.*/ /*Initialize the transformation.*/ g=init_geolocate_meta(&stVec1,meta2); getLoc(g,range,dop, &lat,&phi,&earthRadius); free_geolocate(g); sph2cart(earthRadius,lat,phi,&target); /*Create beam plane unit vectors.*/ vecSub(stVec1.pos,target,&alongBeam); vecNormalize(&alongBeam); up=stVec1.pos; vecNormalize(&up); vecCross(up,alongBeam,&beamNormal); vecNormalize(&beamNormal); vecCross(alongBeam,beamNormal,&upBeam); vecNormalize(&upBeam); /*Find the time when the second satellite crosses the first's beam.*/ t=0.0; stVec2=meta_get_stVec(meta2,t); timeDelta=1.0; while (fabs(timeDelta)>0.00001) { vecSub(stVec1.pos,stVec2.pos,&relPos); timeDelta=vecDot(beamNormal,relPos)/vecDot(beamNormal,stVec2.vel); t+=timeDelta; if (!quietflag) { printf(" Time=%f sec, delta=%f sec\n",t,timeDelta); printf(" Distance from beam plane=%f m\n",vecDot(beamNormal,relPos)); } stVec2=meta_get_stVec(meta2,t); } /*Now we have the second satellite sitting in the plane of the first's beam, so we just separate that position into components along-beam and across-beam, and return.*/ vecSub(stVec2.pos,stVec1.pos,&relPos); *Bp=vecDot(alongBeam,relPos); *Bn=vecDot(upBeam,relPos); }
void DefenseFighterPassiveAttack(Ship *ship,Ship *target,bool rotate) { vector heading; if(!rotate) return; vecSub(heading,target->posinfo.position,ship->posinfo.position); vecNormalize(&heading); aitrackHeading(ship,&heading,0.9999f); }
void CloakAddObjectsInProximity(Ship *cloakship) { Player *playerowner = cloakship->playerowner; Node *objnode = universe.ShipList.head; udword num = universe.ShipList.num; CloakGeneratorStatics *cloakgeneratorstatics; CloakGeneratorSpec *spec = (CloakGeneratorSpec *)cloakship->ShipSpecifics; //maybe don't need Ship *spaceobj; real32 distanceSqr; vector diff; cloakgeneratorstatics = (CloakGeneratorStatics *) ((ShipStaticInfo *)(cloakship->staticinfo))->custstatinfo; while (objnode != NULL) { spaceobj = (Ship *)listGetStructOfNode(objnode); //Rejections... dbgAssert(spaceobj->objtype == OBJ_ShipType); if (spaceobj->playerowner != playerowner) { goto nextnode; // must be players ship inorder to cloak } if( spaceobj->shiptype == SalCapCorvette) { if(((SalCapCorvetteSpec *)spaceobj->ShipSpecifics)->tractorBeam) { goto nextnode; } } if (bitTest(spaceobj->flags,SOF_Cloaked)) { goto nextnode; // if object is cloaked } if(bitTest(spaceobj->flags,SOF_Dead)) { goto nextnode; } if(spaceobj->shiptype == Mothership || spaceobj->shiptype == Carrier) { goto nextnode; } //add more rejections...like collision model. vecSub(diff,spaceobj->posinfo.position,cloakship->posinfo.position); distanceSqr = diff.x*diff.x + diff.y*diff.y + diff.z*diff.z; if(distanceSqr <= cloakgeneratorstatics->CloakingRadiusSqr) { CloakGeneratorAddObj(cloakship, (SpaceObj *) spaceobj); } nextnode: objnode = objnode->next; } }
static void update_system( uFloat *z, uFloat *x_pre, uFloat **K, uFloat *x_post ) { #ifdef PRINT_DEBUG printf( "ekf: updating system\n" ); #endif apply_measurement( x_pre, z_estimate ); /* z_estimate = h ( x_pre ) */ vecSub( z, z_estimate, z_estimate, MEAS_SIZE ); /* z_estimate = z - z_estimate */ matMultVector( K, z_estimate, x_post, STATE_SIZE, MEAS_SIZE ); /* x_post = K * (z- z_estimate) */ vecAdd( x_post, x_pre, x_post, STATE_SIZE ); /* x_post + x_pre + K * (z-z_estimate) */ }
static void triangleDrawTileFast(float *tilebuffer, const Triangle3DSetup &t, int x, int y) { const Vec denom = vecRcp(vec(t.dx1 * t.dy2 - t.dy1 * t.dx2)); const Vec DY2 = vec(t.dy2); const Vec DY3 = vec(t.dy3); const Vec DX2 = vec(t.dx2); const Vec DX3 = vec(t.dx3); const Vec X3 = vec(t.x3); const Vec Y3 = vec(t.y3); const Vec Z1 = vec(t.z1); const Vec Z2 = vec(t.z2); const Vec Z3 = vec(t.z3); const Vec One = vec(1); const Vec Step = vec(0, 1, 2, 3); for(int iy = 0; iy < tileHeight; iy++) { Vec yp = vec(float(y + iy)); float fx = (float)x; const Vec ypos = vecSub(yp, Y3); const Vec dxypos2 = vecMul(DX2, ypos); const Vec dxypos3 = vecMul(DX3, ypos); for(int ix = 0; ix < tileWidth; ix += 4, fx += 4) { void * ptr = &tilebuffer[ix + iy * tileWidth]; const Vec xp = vecAdd(vec(fx), Step); // Calculate barycentric coordinates and depth const Vec xpos = vecSub(xp, X3); const Vec dyxpos2 = vecMul(DY2, xpos); const Vec dyxpos3 = vecMul(DY3, xpos); const Vec delta2 = vecSub(dyxpos2, dxypos2); const Vec delta3 = vecSub(dyxpos3, dxypos3); const Vec t1 = vecMul(delta2, denom); const Vec t2 = vecMul(delta3, denom); const Vec t3 = vecSub(vecSub(One, t1), t2); const Vec tz1 = vecMul(Z1, t1); const Vec tz2 = vecMul(Z2, t2); const Vec tz3 = vecMul(Z3, t3); const Vec z = vecAdd(tz1, vecAdd(tz2, tz3)); // Depth compare const Vec Value = vecLoadAligned(ptr); const Vec DepthCompare = vecCmpGE(Value, z); const Vec Result = vecSel(Value, z, DepthCompare); vecStoreAligned(ptr, Result); } } }
/****************************************************** * time_of_radar: * Refines an estimate of the time the given target was * in the SAR's field of view. It returns the difference * between the new time and the old time.*/ double time_of_radar(meta_parameters *meta,double t_guess,vector targ) { stateVector sat; vector targ2sat; double vs, d_dis, ang; sat=meta_get_stVec(meta,t_guess); vecSub(sat.pos,targ,&targ2sat); ang = angle_anb(sat.vel,targ2sat); d_dis = vecMagnitude(targ2sat)*cosd(ang); vs = vecMagnitude(sat.vel); return -d_dis/vs; }
bool defensefighterCheckInFront(Ship *ship, Bullet *bullet) { vector shipheading; //ship velocity vector shiptobullet; vecSub(shiptobullet, bullet->posinfo.position, ship->posinfo.position); //vecSub(shipheading, ship->posinfo.position, ship->enginePosition); matGetVectFromMatrixCol3(shipheading,ship->rotinfo.coordsys); if(vecDotProduct(shiptobullet, shipheading) > 0) { return TRUE; } return FALSE; }
int triangleClipToPlane(Vec *src, Vec *dst, int size, Vec plane) { int idx = 0; Vec current = *src; for(int i = 1; i < size + 1; i++) { Vec next = src[i % size]; Vec distNext = vecDot(plane, next); Vec distCurrent = vecDot(plane, current); Vec delta = vecSub(distCurrent, distNext); bool goingInNext = vecGetElem(distNext, 0) > 0; bool crossingEdge = goingInNext != vecGetElem(distCurrent, 0) > 0; if(crossingEdge) { // output interpolated vertex Vec ratio = vecMul(distCurrent, vecRcp(delta)); dst[idx] = vecAdd(current, vecMul(vecSub(next, current), ratio)); idx++; } if(goingInNext) { // output vertex as-is dst[idx] = next; idx++; } current = next; } return idx; }
//this function flies the ship to within range of the desired target location and //orients itself to fire. Returns true when in position bool flytoBurstPosition(Ship *ship) { HeavyCorvetteSpec *spec = (HeavyCorvetteSpec *)ship->ShipSpecifics; vector heading; bool ready = FALSE; //maybe track to within gun gimbleness vecSub(heading,spec->burstFireVector,ship->posinfo.position); vecNormalize(&heading); if(aitrackHeadingWithFlags(ship,&heading,0.99f,AITRACKHEADING_IGNOREUPVEC)) { ready = TRUE; } if(!MoveReachedDestinationVariable(ship,&spec->burstFireVector,burstRange)) { aishipFlyToPointAvoidingObjs(ship,&spec->burstFireVector,AISHIP_FastAsPossible,0.0f); return(FALSE); } aitrackZeroVelocity(ship); return(ready); }
void PhysicsWorld::ResolveCollisions() { for(unsigned int i = 0; i < collidedObjectsCnt; i++) { CollisionInfo &inf = collidedObjects[i]; // Just push the contact out by the velocity so we never // end up in a state where the two objects are still intersecting Transform *t = entGetTransform(inf.obj->ent); inf.obj->position = t->GetPosition(); inf.obj->position = vecSub(inf.obj->position, inf.obj->velocity); inf.obj->velocity = vecReflect(inf.obj->velocity, inf.normal); inf.obj->velocity = vecMul(inf.obj->velocity, vec(1, 1, 0, 0)); inf.obj->position = vecAdd(inf.obj->position, inf.obj->velocity); t->SetPosition(inf.obj->position); } collidedObjectsCnt = 0; }
/****************************************************** * latLon2timeSlant: * Convert given latitude and longitude to time, slant * range, and doppler, using state vectors.*/ void latLon2timeSlant(meta_parameters *meta, double lat,double lon, double *time,double *slant,double *dop) { // No effort has been made to make this routine work with // pseudoprojected images. assert (meta->projection == NULL || meta->projection->type != LAT_LONG_PSEUDO_PROJECTION); double t,r,dt=1.0; stateVector sat,targ; int iterations = 0; double RE,RP;/*Radius of earth at equator and poles*/ if (meta->sar->image_type=='P') {/*Map projected image has earth polar and equatorial radii*/ RE=meta->projection->re_major; RP=meta->projection->re_minor; } else {/*Use WGS-84 ellipsoid*/ RE=6378137.0; RP=6356752.314; } targ=get_tv(RE,RP,lat,lon); /* get target state vector*/ t = 0.0; while ((fabs(dt) > time_err)&&(iterations<40)) { dt=time_of_radar(meta,t,targ.pos); t += dt; iterations ++; } sat=meta_get_stVec(meta,t); r = dist(sat.pos,targ.pos);/*r: slant range to target.*/ vecSub(targ.pos,sat.pos,&targ.pos); *time=t; *slant=r; if (dop!=NULL) *dop=fd(meta,sat,targ); }
bool FindBestPlaceForAdvanceSupportFrigate(vector *destination) { Ship *myMothership = aiCurrentAIPlayer->player->PlayerMothership; Ship *enemyMothership = aiuFindEnemyMothership(aiCurrentAIPlayer->player); vector diff; if (myMothership == NULL) { return FALSE; } if (enemyMothership == NULL) { return FALSE; } vecSub(diff,enemyMothership->posinfo.position,myMothership->posinfo.position); vecMultiplyByScalar(diff,ASF_POSITION_TO_ENEMY_MOTHERSHIP); vecAdd(*destination,myMothership->posinfo.position,diff); return TRUE; }
/* take the definition of a camera and a point within the film plane of the camera and generate a RAY x and y both have a range of -0.5 to +0.5 */ Ray *camGenerateRay(Camera *camera, double x, double y, Ray *ray){ Vec direction; Vec cameraX, cameraY; /* work out direction camera is pointing in */ vecSub(&(camera->lookAt), &(camera->at), &direction); vecNormalise(&direction, &direction); /* using that and DOWN, work out the camera axes and normalise */ vecProduct(&direction, &(camera->down), &cameraX); vecProduct(&direction, &cameraX, &cameraY); vecNormalise(&cameraX, &cameraX); vecNormalise(&cameraY, &cameraY); /* finally combine film offset and camera axes to work out film position */ vecScale(x * camera->width, &cameraX, &cameraX); vecScale(y * camera->height, &cameraY, &cameraY); vecScale(camera->depth, &direction, &direction); vecAdd(&cameraX, &direction, &direction); vecAdd(&cameraY, &direction, &direction); rayInit(&(camera->at), &direction, ray); return ray; }
void univUpdateMineWallFormations() { Node *node,*minenode,*tempnode; //Missile *mine, *mineend = NULL, *minestart, *mineendtemp; MineFormationInfo *mineformationinfo; Missile *minestart; vector tempvec; node = universe.MineFormationList.head; while(node != NULL) { mineformationinfo = (MineFormationInfo *) listGetStructOfNode(node); if(mineformationinfo->MineList.num == 9) //use another number other than 0 later..maybe 8? Tunable { //no more mines in formation so destroy this here formation //destroy any effects that are still going //here re-task mines (make not Force Dropped...) if(mineformationinfo->FULL) { //no more mines are going to be added... minenode = mineformationinfo->MineList.head; //set formationinfo to NULL while(minenode != NULL) { minestart = (Missile *) listGetStructOfNode(minenode); minestart->formationinfo = NULL; minenode = minenode->next; } listRemoveAll(&mineformationinfo->MineList); //removes all mine links tempnode = node->next; listDeleteNode(node); //destroys mineformation node = tempnode; continue; } } else { //mines exist in formation if(mineformationinfo->FULL) { minenode = mineformationinfo->MineList.head; while(minenode != NULL) { minestart = (Missile *) listGetStructOfNode(minenode); vecSub(tempvec, minestart->posinfo.position, minestart->formation_position); if(vecMagnitudeSquared(tempvec) > MINE_GONE_TOO_FAR_SQR) { tempnode = minenode->next; minestart->formationinfo = NULL; listRemoveNode(&minestart->formationLink); minenode = tempnode; continue; } minenode = minenode->next; } } } ret: node = node->next; } }
void MineLayerAttackRun(Ship *ship,SpaceObjRotImpTarg *target,AttackSideStep *attacksidestep,AttackSideStepParameters *parameters) { vector trajectory; //real32 dist; real32 range; //real32 temp; // bool didshoot; ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo; Gun *gun; udword numGuns,target_class; GunInfo *guninfo = ship->gunInfo; //vector tmpvec; //real32 randegf; //sdword randeg; //matrix tmpmat; //vector targetheading; MinelayerCorvetteSpec *spec = (MinelayerCorvetteSpec *)ship->ShipSpecifics; MinelayerCorvetteStatics *minelayercorvettestatics; minelayercorvettestatics = (MinelayerCorvetteStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; numGuns = guninfo->numGuns; gun = &guninfo->guns[0]; if(target != NULL) { if(target->objtype == OBJ_ShipType) target_class = ((Ship *)target)->staticinfo->shipclass; else target_class = CLASS_NonCombat; } switch (ship->aistateattack) { case ATTACK_INIT: case APPROACH: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x MINELAYER_ATTACK_APPROACH",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); aishipFlyToShipAvoidingObjs(ship,target,AISHIP_PointInDirectionFlying,0.0f); range = RangeToTarget(ship,target,&trajectory); //lets check if we want to force drop... if(target->objtype == OBJ_ShipType) { if(((Ship *)target)->shiptype == Mothership) { //its a mothership vector tempvec; real32 tempreal; vecSub(tempvec,target->collInfo.collPosition,ship->collInfo.collPosition); tempreal = vecMagnitudeSquared(tempvec); if(tempreal < mothershipDistSqr) { //we're within range of force dropping! ship->aistateattack = DROP_MOTHERSHIP; } break; } } if (range < minelayercorvettestatics->breakInAwayDist) { ship->aistateattack = BREAKPOSITION; spec->aivec.x = 0.0f; spec->aivec.y = 0.0f; spec->aivec.z = 0.0f; } break; case DROP_MOTHERSHIP: { vector tempvec; real32 tempreal; vecSub(tempvec,ship->collInfo.collPosition,target->collInfo.collPosition); tempreal = vecMagnitudeSquared(tempvec); vecNormalize(&tempvec); if(tempreal > mothershipDistSqr2) { ship->aistateattack = ATTACK_INIT; } if(aitrackHeadingWithFlags(ship,&tempvec,0.97f,AITRACKHEADING_IGNOREUPVEC)) { if(MinelayerCorvetteStaticMineDrop(ship,target)) //problem...there will be other targets...bah..lets see.. { MinelayerCorvetteOrderChangedCleanUp(ship); } } break; } case BREAKPOSITION: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAKPOSITION",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); ship->aistateattack = BREAK1; case BREAK1: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAK1",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); //aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); aishipFlyToPointAvoidingObjs(ship,&target->posinfo.position,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); if(range < minelayercorvettestatics->DropRange) { //temp vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); //temp ship->aistateattack = KILL; //within mining range so start dropping spec->aispheretime=0.0f; //reset time; } break; case KILL: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x KILL",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); spec->aispheretime += universe.phystimeelapsed; if(gunCanShoot(ship, gun)) { if(gun->numMissiles > 0) { spec->mineaistate = MINE_DROP_ATTACK; MinelayerCorvetteFire(ship,target); } } if(range > minelayercorvettestatics->DropStopRange) { //out of range.... ship->aistateattack = BREAK2; } if(spec->aispheretime > minelayercorvettestatics->Break2SphereizeFreq) { //time to sphereize; spec->aivec.x =0.0f; spec->aivec.y =0.0f; spec->aivec.z =0.0f; spec->aispheretime = -1000000.0f; // Reset, and never do again till next attack pass... vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x KILL: Adjust for Break2 Sphereizing Godliness Maneuver :)",(udword)ship); #endif } aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); break; case BREAK2: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAK2",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); if(range > minelayercorvettestatics->FlyAwayDist[target_class] || (MoveReachedDestinationVariable(ship,&spec->aivec,minelayercorvettestatics->FlyAwayTolerance))) { //turn around and start over ship->aistateattack = APPROACH; } break; default: dbgAssert(FALSE); break; } }
void applyTransitions(jrPlanet *pPlanet) { if (pPlanet) { float afForce[4]; vecInitDVec(afForce); for (jrPlanet *pOtherPlanet = g_pHead; pOtherPlanet; pOtherPlanet = pOtherPlanet->m_pNext) { if (pPlanet != pOtherPlanet && pOtherPlanet) { float afDistance[3]; vecSub(pPlanet->afPosition, pOtherPlanet->afPosition, afDistance); //get distance float fForce = g_fGravity * (pPlanet->fMass * pOtherPlanet->fMass) / (vecLength(afDistance)); float afNormaliseInput[4]; vecSub(pOtherPlanet->afPosition, pPlanet->afPosition, afNormaliseInput); float afNormaliseOutput[4]; vecInit(afNormaliseOutput); vecNormalise(afNormaliseInput, afNormaliseOutput); afForce[0] = (afForce[0] + afNormaliseOutput[0]); afForce[1] = (afForce[1] + afNormaliseOutput[1]); afForce[2] = (afForce[2] + afNormaliseOutput[2]); if (pPlanet->fMass > pOtherPlanet->fMass) { if (detectCollision(pPlanet, pOtherPlanet, afDistance)) { break; } } } } // calc accV -> afForce/mass pPlanet->afAcceleration[0] = afForce[0] / pPlanet->fMass; pPlanet->afAcceleration[1] = afForce[1] / pPlanet->fMass; pPlanet->afAcceleration[2] = afForce[2] / pPlanet->fMass; // calc new pos if (!pPlanet->m_bFixed) { pPlanet->afPosition[0] = pPlanet->afPosition[0] + (pPlanet->afVelocity[0] * g_fVelocityMultiplier); pPlanet->afPosition[1] = pPlanet->afPosition[1] + (pPlanet->afVelocity[1] * g_fVelocityMultiplier); pPlanet->afPosition[2] = pPlanet->afPosition[2] + (pPlanet->afVelocity[2] * g_fVelocityMultiplier); } // calc new vel pPlanet->afVelocity[0] = pPlanet->afVelocity[0] + pPlanet->afAcceleration[0]; pPlanet->afVelocity[1] = pPlanet->afVelocity[1] + pPlanet->afAcceleration[1]; pPlanet->afVelocity[2] = pPlanet->afVelocity[2] + pPlanet->afAcceleration[2]; // apply drag pPlanet->afAcceleration[0] = pPlanet->afAcceleration[0] * g_fDamping; pPlanet->afAcceleration[1] = pPlanet->afAcceleration[1] * g_fDamping; pPlanet->afAcceleration[2] = pPlanet->afAcceleration[2] * g_fDamping; // end if (pPlanet->iHistoryCount < g_iHistoryVariableLength - 4) { pPlanet->iHistoryCount = pPlanet->iHistoryCount + 3; } else { pPlanet->iHistoryCount = 0; } pPlanet->afPositionHistory[pPlanet->iHistoryCount] = pPlanet->afPosition[0]; pPlanet->afPositionHistory[pPlanet->iHistoryCount + 1] = pPlanet->afPosition[1]; pPlanet->afPositionHistory[pPlanet->iHistoryCount + 2] = pPlanet->afPosition[2]; if (pPlanet->fRotationAngle > 359.0f) { pPlanet->fRotationAngle = 0.0f; } else { pPlanet->fRotationAngle = pPlanet->fRotationAngle += 1.0f; } } }
void triangleVertexShading(JmJob *data) { VertexJob v; dmaBlockGet(&v, (uintptr_t)data->p1, sizeof(VertexJob), DmaTag); Vec halfSizeAdd = vec(0.5f * sw, 0.5f * sh, 0, 1); Vec halfSizeMul = vec(0.5f * sw, -0.5f * sh, 1, 0); Vec zero = vec(0); Mat transform; matMul(&transform, v.projection, v.world); while(true) { unsigned int k = interlockedExchangeAdd(v.counter, VerticesAtATime); if(k >= v.end) break; unsigned int end = std::min(k + VerticesAtATime, v.end); unsigned int num = end - k; unsigned int numtris = num / 3; #ifndef PLATFORM_PS3_SPU Triangle3D vertexShadingTris[TriangleAtATime]; #endif dmaBlockGet(vertexShadingTris, (uintptr_t)&v.input[k], numtris * sizeof(Triangle3D), DmaTag); for(unsigned int u = 0; u < numtris; u++) { const Triangle3D &tri = vertexShadingTris[u]; Triangle3D triOut[5]; Vec vtx[8]; int numTrisOut = 1; if(g_EnableBackfaceCulling) { // We can't do the backface culling using a determinant of a 2x2 matrix // in screen space because then we would have 'holes' in the output data // therefor it happens here, in wordspace. Vec e1 = vecSub(tri.p3, tri.p1); Vec e2 = vecSub(tri.p2, tri.p1); Vec n = vecCross(e1, e2); Vec a = vecDot(v.camerapos, n); if(vecGetElem(a, VecComponent::X) > 0) continue; } // perspective project matMulVec(&triOut[0].p1, transform, tri.p1); matMulVec(&triOut[0].p2, transform, tri.p2); matMulVec(&triOut[0].p3, transform, tri.p3); // cull against znear Vec m1 = vecCmpLE(vecSplat<VecComponent::Z>(triOut[0].p1), zero); Vec m2 = vecCmpLE(vecSplat<VecComponent::Z>(triOut[0].p2), zero); Vec m3 = vecCmpLE(vecSplat<VecComponent::Z>(triOut[0].p3), zero); Vec c2 = vecAnd(vecAnd(m1, m2), m3); #ifdef PLATFORM_PS3 vec_uint4 ones = (vec_uint4){0xffffffff,0xffffffff,0xffffffff,0xffffffff}; if(vec_all_eq((vec_uint4)c2, ones)) continue; #else int result = vecMaskToInt(c2); if(result == 15) continue; // discard, all behind nearz #endif #if 1 // clip triangles that intersect znear static const int NumVerticesInATriangle = 3; int numVertsOut = triangleClipToPlane( (Vec*)&triOut[0], vtx, NumVerticesInATriangle, vec(0, 0, 1, 0) ); // Very simple triangulation routine numTrisOut = 0; for(int i = 2; i < numVertsOut; i++) { triOut[numTrisOut].p1 = vtx[0]; triOut[numTrisOut].p2 = vtx[i]; triOut[numTrisOut].p3 = vtx[i - 1]; numTrisOut++; } #endif for(int i = 0; i < numTrisOut; i++) { // perspective divide triOut[i].p1 = vecMul(triOut[i].p1, vecRcp(vecSplat<VecComponent::W>(triOut[i].p1))); triOut[i].p2 = vecMul(triOut[i].p2, vecRcp(vecSplat<VecComponent::W>(triOut[i].p2))); triOut[i].p3 = vecMul(triOut[i].p3, vecRcp(vecSplat<VecComponent::W>(triOut[i].p3))); // transform to screen space Vec r1 = vecMadd(triOut[i].p1, halfSizeMul, halfSizeAdd); Vec r2 = vecMadd(triOut[i].p2, halfSizeMul, halfSizeAdd); Vec r3 = vecMadd(triOut[i].p3, halfSizeMul, halfSizeAdd); #ifdef PLATFORM_PS3_SPU Triangle3DSetup &r = setup[s][sidx]; #else Triangle3DSetup r; #endif memcpy(&r.x1, &r1, sizeof(float) * 3); memcpy(&r.x2, &r2, sizeof(float) * 3); memcpy(&r.x3, &r3, sizeof(float) * 3); // deltas r.dx1 = r.x1 - r.x2; r.dx2 = r.x2 - r.x3; r.dx3 = r.x3 - r.x1; r.dy1 = r.y1 - r.y2; r.dy2 = r.y2 - r.y3; r.dy3 = r.y3 - r.y1; #ifdef PLATFORM_PS3_SPU sidx++; if(sidx >= MaxSetupBuffered) { dmaWaitAll(1 << DmaListTag); unsigned int l = interlockedExchangeAdd(v.outputCnt, sidx); for(unsigned int u = 0; u < sidx; u++) { setuplist[u].notify = 0; setuplist[u].reserved = 0; setuplist[u].size = sizeof(Triangle3DSetup); setuplist[u].eal = (uintptr_t)&v.output[u + l]; } cellDmaListPut(setup[s], 0, setuplist, sizeof(setuplist), DmaListTag, 0, 0); sidx = 0; s ^= 1; } #else unsigned int l = interlockedExchangeAdd(v.outputCnt, 1); if(l >= MaxTrianglesDrawn) { interlockedExchangeSub(v.outputCnt, 1); break; } else dmaBlockPut(&r, (uintptr_t)&v.output[l], sizeof(Triangle3DSetup), DmaTag); #endif } } } #ifdef PLATFORM_PS3_SPU if(sidx > 0) { dmaWaitAll(1 << DmaListTag); unsigned int l = interlockedExchangeAdd(v.outputCnt, sidx); for(unsigned int u = 0; u < sidx; u++) { setuplist[u].notify = 0; setuplist[u].reserved = 0; setuplist[u].size = sizeof(Triangle3DSetup); setuplist[u].eal = (uintptr_t)&v.output[u + l]; } cellDmaListPut(setup[s], 0, setuplist, sidx * sizeof(CellDmaListElement), DmaListTag + 1, 0, 0); dmaWaitAll(1 << (DmaListTag + 1)); } #endif }
void adentu_event_gfc_attend (AdentuModel *model, AdentuEvent *event) { AdentuAtom *grain = model->grain; AdentuAtom *fluid = model->fluid; double dT = event->time - model->elapsedTime; adentu_event_mpc_cuda_integrate (grain, model->gGrid, model->accel, dT); adentu_event_mpc_cuda_integrate (fluid, model->fGrid, model->accel, dT); adentu_grid_set_atoms (model->gGrid, grain, model); adentu_grid_set_atoms (model->fGrid, fluid, model); int owner = event->owner; int partner = event->partner; vec3f *gvel = &grain->vel[owner]; vec3f *fvel = &fluid->vel[partner]; vec3f *gpos = &grain->pos[owner]; vec3f *fpos = &fluid->pos[partner]; double gmass = grain->mass[owner]; double fmass = fluid->mass[partner]; vec3f pBefore, eBefore; vec3f pAfter, eAfter; vec3f dpos, dvel, n, dp; double eBeforeTotal, eAfterTotal, mod, dpAux; pBefore.x = gmass * gvel->x + fmass * fvel->x; pBefore.y = gmass * gvel->y + fmass * fvel->y; pBefore.z = gmass * gvel->z + fmass * fvel->z; eBefore.x = 0.5 * gmass * (gvel->x * gvel->x) + 0.5 * fmass * (fvel->x * fvel->x); eBefore.y = 0.5 * gmass * (gvel->y * gvel->y) + 0.5 * fmass * (fvel->y * fvel->y); eBefore.x = 0.5 * gmass * (gvel->z * gvel->z) + 0.5 * fmass * (fvel->z * fvel->z); eBeforeTotal = eBefore.x + eBefore.y + eBefore.z; vecSub (dpos, *fpos, *gpos); n = dpos; mod = vecMod (n); n.x /= mod; n.y /= mod; n.z /= mod; vecSub (dvel, *fvel, *gvel); dpAux = -2.0 * ((gmass * fmass) / (gmass + fmass)) * vecDot (dvel, n); dp.x = dpAux * n.x; dp.y = dpAux * n.y; dp.z = dpAux * n.z; gvel->x -= (dp.x / gmass); gvel->y -= (dp.y / gmass); gvel->z -= (dp.z / gmass); fvel->x -= (dp.x / fmass); fvel->y -= (dp.y / fmass); fvel->z -= (dp.z / fmass); pAfter.x = gmass * gvel->x + fmass * fvel->x; pAfter.y = gmass * gvel->y + fmass * fvel->y; pAfter.z = gmass * gvel->z + fmass * fvel->z; eAfter.x = 0.5 * gmass * (gvel->x * gvel->x) + 0.5 * fmass * (fvel->x * fvel->x); eAfter.y = 0.5 * gmass * (gvel->y * gvel->y) + 0.5 * fmass * (fvel->y * fvel->y); eAfter.z = 0.5 * gmass * (gvel->z * gvel->z) + 0.5 * fmass * (fvel->z * fvel->z); eAfterTotal = eAfter.x + eAfter.y + eAfter.z; vecSub (dvel, *fvel, *gvel); vecSub (dpos, *fpos, *gpos); grain->nCol[owner]++; fluid->nCol[partner]++; }
void doKamikazeAttack(Ship *ship,SpaceObjRotImpTarg *target) { real32 mag,dist,range,shipvel; vector destination,trajectory,heading,shipheading,EinsteinVelocity; ShipStaticInfo *shipstaticinfo = ship->staticinfo; vecSub(trajectory,target->collInfo.collPosition,ship->posinfo.position); mag = vecMagnitudeSquared(trajectory); dist = fsqrt(mag); destination = trajectory; vecNormalize(&destination); heading = destination; //this hokey fudge factor is needed so the kamikaze ship doesn't //slow down as it reaches its destination mag = dist + 500.0f; vecScalarMultiply(destination,destination,mag); vecAddTo(destination,target->collInfo.collPosition); range = RangeToTargetGivenDist(ship,target,dist); switch(ship->kamikazeState) { case K_Start: //if within a threshold range bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); if(range < 500.0f) { //calculate flyby dist matGetVectFromMatrixCol3(shipheading, ship->rotinfo.coordsys); vecScalarMultiply(shipheading,shipheading,kamikazeFlyByDist); vecAdd(ship->kamikazeVector,shipheading,target->collInfo.collPosition); ship->kamikazeState = K_TurnAround; } ship->kamikazeState = K_Ram; break; case K_Ram: if (range < 400.0f) { ship->kamikazeState = K_Yell; } case K_Ram2: //lets use...mmmmm..twister theor...no...relativity vecSub(EinsteinVelocity,ship->posinfo.velocity,target->posinfo.velocity); shipvel = fsqrt(vecMagnitudeSquared(EinsteinVelocity)); if(ship->shiptype == MinelayerCorvette) { ((MinelayerCorvetteSpec *)(ship->ShipSpecifics))->mineaistate = MINE_DROP_ATTACK; } else if (ship->shiptype == DefenseFighter) { goto dontshoot; } if (isShipStaticInterceptor(shipstaticinfo)) { if (range < shipstaticinfo->bulletRange[ship->tacticstype]) { GenericInterceptorStatics *interceptorstat = (GenericInterceptorStatics *)shipstaticinfo->custstatinfo; uword targetIndex; if (target->objtype == OBJ_ShipType) { targetIndex = (uword)((ShipStaticInfo *)target->staticinfo)->shipclass; } else { targetIndex = (uword)NUM_CLASSES; } if (GenericInterceptorCanFire(ship,target,&trajectory,interceptorstat->triggerHappy[ship->tacticstype][targetIndex])) { ship->staticinfo->custshipheader.CustShipFire(ship,target); } } } else { gunShootGunsAtTarget(ship,target,range,&trajectory); } dontshoot: aishipFlyToPointAvoidingObjs(ship,&destination,AISHIP_PointInDirectionFlying | AISHIP_FirstPointInDirectionFlying | AISHIP_FastAsPossible,0.0f); if(range < 1500.0f) { bitSet(ship->specialFlags,SPECIAL_KamikazeCrazyFast); } else { bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); } /* if(range < 400.0f && (shipvel < ship->staticinfo->staticheader.maxvelocity*0.7f || vecDotProduct(trajectory,heading) < 0)) { //ship is inside 400.0f, and isn't faceing ship, or isn't //going fast enough //calculate flyby dist matGetVectFromMatrixCol3(shipheading, ship->rotinfo.coordsys); vecScalarMultiply(shipheading,shipheading,kamikazeFlyByDist); vecAdd(ship->kamikazeVector,shipheading,target->posinfo.position); ship->kamikazeState = K_TurnAround; } */ break; case K_TurnAround: bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); aishipFlyToPointAvoidingObjs(ship,&ship->kamikazeVector,AISHIP_PointInDirectionFlying | AISHIP_FirstPointInDirectionFlying | AISHIP_FastAsPossible,0.0f); if(MoveReachedDestinationVariable(ship,&ship->kamikazeVector,300.0f)) ship->kamikazeState = K_TurnAround2; break; case K_TurnAround2: bitClear(ship->specialFlags,SPECIAL_KamikazeCrazyFast); if(aitrackHeadingWithFlags(ship,&heading,0.90f,AITRACKHEADING_IGNOREUPVEC)) ship->kamikazeState = K_Ram; break; case K_Yell: // speechEvent(ship, COMM_LInt_Kamikaze, 0); battleChatterAttempt(SOUND_EVENT_DEFAULT, BCE_Kamikaze, ship, SOUND_EVENT_DEFAULT); ship->kamikazeState = K_Ram2; break; } //fire guns here... // // //Sound note: Could put in kamikaze state change here after // getting to within a certain distance of target // // ask bryce how to... }
void DrawGLScene5() { Vec v1,v2,v3,v4,v5,norm; glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glLoadIdentity(); glLightfv(GL_LIGHT0, GL_POSITION,LightPosition); glTranslatef(-1.5f,0.0f,-6.0f); glRotatef(rtri,0.0f,1.0f,0.0f); glColor3f(0.8f,0.0f,0.0f); glBegin(GL_TRIANGLES); //Notice the process here... //1. build verts //2. make 2 vectors //3. find cross product. that's the normal //4. normalize it to a length of 1 vecMake( 0.0f, 1.0f, 0.0f, v1); vecMake(-1.0f,-1.0f, 1.0f, v2); vecMake( 1.0f,-1.0f, 1.0f, v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); vecMake( 0.0f, 1.0f, 0.0f,v1); vecMake( 1.0f,-1.0f, 1.0f,v2); vecMake( 1.0f,-1.0f,-1.0f,v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); vecMake( 0.0f, 1.0f, 0.0f,v1); vecMake( 1.0f,-1.0f,-1.0f,v2); vecMake(-1.0f,-1.0f,-1.0f,v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); vecMake( 0.0f, 1.0f, 0.0f,v1); vecMake(-1.0f,-1.0f,-1.0f,v2); vecMake(-1.0f,-1.0f, 1.0f,v3); vecSub(v2,v1,v4); vecSub(v3,v1,v5); vecCrossProduct(v4,v5,norm); vecNormalize(norm); glNormal3fv(norm); glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3); glEnd(); glLoadIdentity(); glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); glTranslatef(1.5f,0.0f,-7.0f); glRotatef(rquad,1.0f,1.0f,1.0f); glColor3f(0.0f,0.5f,1.0f); glBegin(GL_QUADS); //top //notice the normal being set glNormal3f( 0.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // bottom of cube glNormal3f( 0.0f, -1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // front of cube glNormal3f( 0.0f, 0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // back of cube. glNormal3f( 0.0f, 0.0f, -1.0f); glVertex3f( 1.0f,-1.0f,-1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // left of cube glNormal3f( -1.0f, 0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // Right of cube glNormal3f( 1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); glVertex3f( 1.0f,-1.0f,-1.0f); glEnd(); rtri+=2.0f; rquad-=1.0f; }