/*----------------------------------------------------------------------------- Name : nisShipEulerToMatrix Description : Builds a coordinate system matrix from a heading,pitch,bank triplicate. Inputs : rotVector - vectror whose members represent the heading, pitch and bank Outputs : coordsys - where to store the matrix Return : ----------------------------------------------------------------------------*/ void nisShipEulerToMatrix(matrix *coordsys, vector *rotVector) { matrix rotation, tempMatrix; vector rotateAbout = {-1.0f, 0.0f, 0.0f}; *coordsys = IdentityMatrix; //rotate about up vector (heading) nisRotateAboutVector((real32 *)&rotation, &rotateAbout, rotVector->x); matMultiplyMatByMat(&tempMatrix, &rotation, coordsys); *coordsys = tempMatrix; //rotate about heading vector (pitch in lightwave, bank actually) matGetVectFromMatrixCol3(rotateAbout, *coordsys); nisRotateAboutVector((real32 *)&rotation, &rotateAbout, rotVector->y); matMultiplyMatByMat(&tempMatrix, &rotation, coordsys); *coordsys = tempMatrix; //rotate about heading vector (bank in lightwave, pitch actually) matGetVectFromMatrixCol2(rotateAbout, *coordsys); nisRotateAboutVector((real32 *)&rotation, &rotateAbout, -rotVector->z); matMultiplyMatByMat(&tempMatrix, &rotation, coordsys); *coordsys = tempMatrix; }
bool madLinkInGetDoorInfo(Ship *ship, matrix *coordsys, vector *position) { sdword madIndex, gunIndex; vector positiont; matrix coordsyst; madIndex = madBindingIndexFindByName(ship->staticinfo->madStatic->header, "Hangardoor"); gunIndex = madGunBindingIndexFindByName(ship->staticinfo, "Hangardoor"); dbgAssertOrIgnore(madIndex != -1); dbgAssertOrIgnore(gunIndex != -1); madAnimBindingMatrix(&coordsyst,&positiont,ship,gunIndex, madIndex); matMultiplyMatByMat(coordsys,&ship->rotinfo.coordsys,&coordsyst); //matMultiplyVecByMat(position,&positionSS,&ship->rotinfo.coordsys); matMultiplyMatByVec(position,&ship->rotinfo.coordsys,&positiont); vecAddTo(*position,ship->posinfo.position); return TRUE; }
void addMonkeyResearchShipChangePosition(Ship *dockwith, Ship *ship,sdword dockindex) { DockStaticPoint *dockwithstaticpoint; vector coneheadingInWorldCoordSysDockWith,DockWithHeading,destination,DockWithUp,destinationoffset; vector desiredHeading,desiredUp,conepositionInWorldCoordSysDockWith,tmpvec; real32 theta; matrix rotmatrix,tmpmat; ResearchShipStatics *resstatics; resstatics = (ResearchShipStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; dbgAssertOrIgnore(dockwith != NULL); //if we're calling this there should be another reserach station available somewhere if(ship->shiprace == R1) { dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex]; matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal); matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys) destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R1final_dock_distance; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R1final_dock_distance; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R1final_dock_distance; vecAdd(destination,dockwith->posinfo.position, destinationoffset); if(((ResearchShipSpec *)ship->ShipSpecifics)->pie_plate_num == 0) { //ship is docking on'a'top so add upwards factor matGetVectFromMatrixCol1(DockWithUp,dockwith->rotinfo.coordsys); vecScalarMultiply(DockWithUp,DockWithUp,resstatics->R1VerticalDockDistance); vecAdd(destination,destination,DockWithUp); } theta = DEG_TO_RAD(60); matMakeRotAboutX(&rotmatrix,(real32) cos(theta),(real32) sin(theta)); matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix); //share a lot of these things...later... ship->rotinfo.coordsys = tmpmat; ship->posinfo.position = destination; } else { //r2 positioning dockwithstaticpoint = &dockwith->staticinfo->dockStaticInfo->dockstaticpoints[dockindex]; matMultiplyMatByVec(&coneheadingInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->conenormal); matMultiplyMatByVec(&conepositionInWorldCoordSysDockWith,&dockwith->rotinfo.coordsys,&dockwithstaticpoint->position); vecAddTo(conepositionInWorldCoordSysDockWith,dockwith->posinfo.position); matGetVectFromMatrixCol3(DockWithHeading,dockwith->rotinfo.coordsys) destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*resstatics->R2DockFinalDistance; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*resstatics->R2DockFinalDistance; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*resstatics->R2DockFinalDistance; vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset); desiredHeading = coneheadingInWorldCoordSysDockWith; if(dockindex == 0) { matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys); } else if(dockindex == 1) { matGetVectFromMatrixCol3(desiredUp,dockwith->rotinfo.coordsys); } else if(dockindex == 2) { desiredUp = DockWithHeading; } else if(dockindex == 3) { theta = DEG_TO_RAD(60); matMakeRotAboutZ(&rotmatrix,(real32) cos(theta),(real32) sin(theta)); matMultiplyMatByMat(&tmpmat, &dockwith->rotinfo.coordsys, &rotmatrix); matGetVectFromMatrixCol1(desiredUp,tmpmat); } else if(dockindex == 4) { destinationoffset.x = coneheadingInWorldCoordSysDockWith.x*100; destinationoffset.y = coneheadingInWorldCoordSysDockWith.y*100; destinationoffset.z = coneheadingInWorldCoordSysDockWith.z*100; vecAdd(destination,conepositionInWorldCoordSysDockWith, destinationoffset); matGetVectFromMatrixCol1(desiredUp,dockwith->rotinfo.coordsys); vecScalarMultiply(desiredHeading,desiredHeading,-1.0f); } else { dbgAssertOrIgnore(FALSE); //shouldget here. } vecNormalize(&desiredUp); matPutVectIntoMatrixCol1(desiredUp,ship->rotinfo.coordsys); vecCrossProduct(tmpvec,desiredHeading,desiredUp); matPutVectIntoMatrixCol2(tmpvec,ship->rotinfo.coordsys); matPutVectIntoMatrixCol3(desiredHeading,ship->rotinfo.coordsys); ship->posinfo.position = destination; ship->posinfo.velocity.x = 0.0f; ship->posinfo.velocity.y = 0.0f; ship->posinfo.velocity.z = 0.0f; } }
void ResearchShipHouseKeep(Ship *ship) { ResearchShipSpec *spec = (ResearchShipSpec *)ship->ShipSpecifics; SelectCommand selection; vector up,destination,desiredheading,newup; vector univup = {0.0f,0.0f,1.0f}; bool InParadeandMoving = FALSE; matrix rot_matrix,tmpmat,rotmat; real32 radangle; ResearchShipStatics *researchshipstatics; researchshipstatics = (ResearchShipStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; if(bitTest(ship->specialFlags,SPECIAL_StopForResearchDocking)) { vecScalarMultiply(ship->posinfo.velocity,ship->posinfo.velocity,0.94); vecScalarMultiply(ship->rotinfo.rotspeed,ship->rotinfo.rotspeed,0.94); bitSet(ship->dontapplyforceever,1); bitSet(ship->dontrotateever,1); } else { bitClear(ship->dontapplyforceever,1); bitClear(ship->dontrotateever,1); } if(ship->flags & SOF_Slaveable) { if(ship->slaveinfo->flags & SF_MASTER) { CommandToDo *command = getShipAndItsCommand(&universe.mainCommandLayer,ship); if(command != NULL) { //ship may be in parade... if(command->ordertype.order == COMMAND_MILITARY_PARADE) { //ship is in parade CommandToDo *ashipCom = getShipAndItsCommand(&universe.mainCommandLayer,command->militaryParade->aroundShip); if(ashipCom != NULL) { //probably shouldn't be null regardless..should be equal to command..but ohwell if(ashipCom->ordertype.order == COMMAND_MOVE || ashipCom->ordertype.order == COMMAND_ATTACK || ashipCom->ordertype.order == COMMAND_SPECIAL || ashipCom->ordertype.order == COMMAND_MP_HYPERSPACING) { InParadeandMoving = TRUE; spec->rotate_state = ROTATE_WAIT; } } //in parade if(!InParadeandMoving) { if(bitTest(ship->specialFlags,SPECIAL_ParadeNeedTomoveCloser)) { InParadeandMoving = TRUE; spec->rotate_state = ROTATE_WAIT; } } } } } } if(ship->flags & SOF_Slaveable) { //ship is slaveable bitSet(ship->flags,SOF_DontDrawTrails); ship->autostabilizeship = FALSE; // never have univupdate autostabilize research ships if(ship->slaveinfo->flags & SF_MASTER) { //ship is a master if(!InParadeandMoving) { if(ship->shiprace == R1) { //ship is a race 1 MASTER research ship... //i.e. it controls the motion switch(spec->rotate_state) { case ANGLE_ESTABLISH: //establishes the angle at which the station is supposed to rotate at break; case ROTATE_WAIT: //wait to rotate if(ship->slaveinfo->slaves.num >= 5) { //correct # of ships... if(!ship_is_moving(ship)) { if(!spec->prepshipforanother) { //no ships are coming to dock //do up vector tracking! //Later Calculate this vector ONCE at code start up...Let Daly do it //and get as a static value radangle = DEG_TO_RAD(researchshipstatics->RotationAngle); matMakeRotAboutX(&rotmat,(real32) cos(radangle),(real32) sin(radangle)); matMultiplyMatByVec(&newup, &rotmat, &univup); //matGetVectFromMatrixCol3(desiredHeading,ship->rotinfo.coordsys); if(aitrackHeadingWithFlags(ship,&newup,0.96f,AITRACKHEADING_IGNOREUPVEC)) { spec->rotate_state = ROTATE_DO; getRotatePoint(ship, &spec->rotate_point,&spec->rotate_distance); } } } if(!spec->have_removed_from_parade) { spec->have_removed_from_parade = TRUE; selection.numShips = 1; selection.ShipPtr[0] = ship; //RemoveShipsFromDoingStuff(&universe.mainCommandLayer,&selection); //clHalt(&universe.mainCommandLayer,&selection); } } break; case ROTATE_STOP: case ROTATE_STOP_QUICK: case ROTATE_DO: ship->posinfo.isMoving = ISMOVING_MOVING | ISMOVING_ROTATING; make_all_slaves_moving(ship); if(ship->slaveinfo->slaves.num < 5) { //don't rotate anymore because slaves dropped below threhold for whatever reasons! spec->rotate_state = ROTATE_STOP; break; } if(spec->prepshipforanother) { //need to prep ship for a docking ship.. spec->rotate_state = ROTATE_STOP; } else if(ship_is_moving(ship)) { //ship is being moved spec->rotate_state = ROTATE_STOP_QUICK; } else { spec->rotate_state = ROTATE_DO; } //matGetVectFromMatrixCol3(heading,ship->rotinfo.coordsys); matGetVectFromMatrixCol1(up,ship->rotinfo.coordsys); //vecScalarMultiply(rotate_point, heading, -250.0f); //vecAdd(rotate_point,rotate_point, ship->posinfo.position); switch(spec->rotate_state) { case ROTATE_DO: if(spec->theta >= researchshipstatics->max_rotate) spec->theta = researchshipstatics->max_rotate; else spec->theta += researchshipstatics->rotate_acelleration; break; case ROTATE_STOP_QUICK: spec->theta *= researchshipstatics->rotate_slow; spec->theta *= researchshipstatics->rotate_slow; case ROTATE_STOP: if(spec->theta <= 0.00001f) { spec->theta = 0.0f; spec->rotate_state = ROTATE_WAIT; break; } else spec->theta *= researchshipstatics->rotate_slow; break; default: dbgAssertOrIgnore(FALSE); break; } matMakeRotAboutX(&rot_matrix,(real32) cos(spec->theta),(real32) sin(spec->theta)); //matMultiplyMatByMat(&tmpmat, &rot_matrix, &ship->rotinfo.coordsys); matMultiplyMatByMat(&tmpmat, &ship->rotinfo.coordsys, &rot_matrix); //vecSub(tmpvec, ship->posinfo.position, spec->rotate_point); //dist = vecMagnitudeSquared(tmpvec); //dist = fsqrt(dist); matGetVectFromMatrixCol3(desiredheading,tmpmat); vecScalarMultiply(destination, desiredheading, spec->rotate_distance); //old was dist vecAdd(destination,destination,spec->rotate_point); ship->posinfo.position = destination; ship->rotinfo.coordsys = tmpmat; univUpdateObjRotInfo((SpaceObjRot *)ship); break; default: dbgMessagef("Shouldn't Get Here...unknown Research Ship Rotate State"); dbgAssertOrIgnore(FALSE); break; } } else { //Ship is an R2 Master...so rotate differently switch(spec->rotate_state) { case ANGLE_ESTABLISH: break; case ROTATE_WAIT: //wait to rotate if(ship->slaveinfo->slaves.num >= 3) { //correct # of ships... if(!spec->prepshipforanother && !ship_is_moving(ship)) { //no ships are coming to dock radangle = DEG_TO_RAD(researchshipstatics->RotationAngle); matMakeRotAboutX(&rotmat,(real32) cos(radangle),(real32) sin(radangle)); matMultiplyMatByVec(&newup, &rotmat, &univup); if(aitrackHeadingWithFlags(ship,&newup,0.96f,AITRACKHEADING_IGNOREUPVEC)) { spec->rotate_state = ROTATE_DO; } } else { vecSet(ship->rotinfo.rotspeed,0.0f,0.0f,0.0f); vecSet(ship->rotinfo.torque,0.0f,0.0f,0.0f); } } if(ship->slaveinfo->slaves.num >= 1) { //correct # of ships... if(!spec->have_removed_from_parade) { spec->have_removed_from_parade = TRUE; selection.numShips = 1; selection.ShipPtr[0] = ship; //RemoveShipsFromDoingStuff(&universe.mainCommandLayer,&selection); //clHalt(&universe.mainCommandLayer,&selection); } } break; case ROTATE_STOP: case ROTATE_STOP_QUICK: case ROTATE_DO: ship->posinfo.isMoving = ISMOVING_MOVING | ISMOVING_ROTATING; make_all_slaves_moving(ship); if(ship->slaveinfo->slaves.num < 3) { //don't rotate anymore because slaves dropped below threhold for whatever reasons! spec->rotate_state = ROTATE_STOP; break; } if(spec->prepshipforanother) { //need to prep ship for a docking ship.. spec->rotate_state = ROTATE_STOP; } if(ship_is_moving(ship)) { //ship is being moved spec->rotate_state = ROTATE_STOP_QUICK; } switch(spec->rotate_state) { case ROTATE_DO: if(spec->theta >= researchshipstatics->max_rotate) spec->theta = researchshipstatics->max_rotate; else spec->theta += researchshipstatics->rotate_acelleration; break; case ROTATE_STOP_QUICK: spec->theta *= researchshipstatics->rotate_slow; spec->theta *= researchshipstatics->rotate_slow; case ROTATE_STOP: if(spec->theta <= 0.00001f) { spec->theta = 0.0f; spec->rotate_state = ROTATE_WAIT; break; } else spec->theta *= researchshipstatics->rotate_slow; break; default: dbgAssertOrIgnore(FALSE); break; } matMakeRotAboutZ(&rot_matrix,(real32) cos(spec->theta),(real32) sin(spec->theta)); tmpmat = ship->rotinfo.coordsys; matMultiplyMatByMat(&ship->rotinfo.coordsys,&tmpmat,&rot_matrix); univUpdateObjRotInfo((SpaceObjRot *)ship); break; default: dbgMessagef("Shouldn't Get Here...unknown Research Ship Rotate State"); dbgAssertOrIgnore(FALSE); break; } } } } else { vecScalarMultiply(ship->posinfo.velocity,ship->posinfo.velocity, 0.0f); } } }