// Fonction de calcul de la cinématique inverse : Résultat vrais ou faux en fonction de l'objectif donnée (accessible ou non) int ComputeIK(int x, int y) { /// Variables locales float ex,ey; // Vecteur déplacement float sin2,cos2; // SINE ry COSINE de l'ANGLE 2 float angle1,angle2; // ANGLE 1 et 2 en RADIANS float tan1; // TAN de ANGLE 1 // Changement de repère (inversion de l'axe Y) y = m_Height - y - 1; //.. ex = x - m_UpArm.pos.x; ey = y - m_UpArm.pos.y; cos2 = (pow(ex,2) + pow(ey,2) - pow(UpArm_Length,2) - pow(LowArm_Length,2) )/ (2*UpArm_Length*LowArm_Length); if (cos2 >1 && cos2 <-1) return 0; angle2 = acos (cos2); sin2 = sin (angle2); tan1 = (-(LowArm_Length*sin2*ex) + ((UpArm_Length+(LowArm_Length * cos2))*ey) ) / ((LowArm_Length*sin2*ey) + (UpArm_Length+(LowArm_Length*cos2))*ex); angle1 = atan (tan1); m_UpArm.rot.z = RADTODEG(angle1); m_LowArm.rot.z = RADTODEG(angle2); return 1; }
// applies the transformation needed to bring the given vector to the x axis. void Matrix4::transvecinv(float x, float y, float z) { double theta = atan2(y,x); double length = sqrt(y*y + x*x); double phi = atan2((double) z, length); rot((float) RADTODEG(phi), 'y'); rot((float) RADTODEG(-theta), 'z'); }
// --------------------------------------------------------------------------- // Calculate angle of triangle, when adjacent and opposite sides are known // --------------------------------------------------------------------------- // TInt CAlfExAnalogDialerControl::Angle(TReal32 aAdjacent, TReal32 aOpposite) { if (aAdjacent == 0) { aAdjacent = 0.01; } if (aOpposite == 0) { aOpposite = 0.01; } TReal angle; Math::ATan(angle, Abs(aOpposite / aAdjacent)); if (aAdjacent < 0 && aOpposite > 0) { angle = KPi - angle; } else if (aAdjacent < 0 && aOpposite < 0) { angle = KPi + angle; } else if (aAdjacent > 0 && aOpposite < 0) { angle = 2* KPi - angle; } return RADTODEG(angle); }
double Angle3 (Vector3 vector1, Vector3 vector2, AngleMode mode) { double angle = acos (Dot3 (vector1, vector2) / (Mag3 (vector1) * Mag3 (vector2))); // Angle in given mode between two vectors switch (mode) // Get the angle mode { case kDegrees: // Degrees case angle = RADTODEG(angle); // Convert angle to radians break; // Break out of switch statement case kGradians: // Gradians case angle = RADTOGRAD(angle); // Convert angle to radians break; // Break out of switch statement case kRadians: // Radians case break; // Break out of switch statement default: NOBREAK_MESSAGE("Unsupported mode: Angle3 failed","1"); angle = 0.0;// Invalid case break; // Break out of switch statement } return angle; // Return the angle between vectors in radians }
void Renderer::drawAsteroids() { for (unsigned int i=0; i<game->asteroides.size(); i++ ) { float x = game->asteroides[i]->position[0]; float y = game->asteroides[i]->position[1]; int vc = game->asteroides[i]->vertexCount; float angle = game->asteroides[i]->fOrientation; // tego tu nie ma być morf // game->asteroides[i]->move(); glPushMatrix (); glLineWidth (3.0f); glTranslatef(x,y,0); glRotatef( RADTODEG(angle) , 0, 0, 1 ); glBegin (GL_LINE_LOOP); for(int j=0; j<vc; j++) { x = game->asteroides[i]->vertices[j].x; y = game->asteroides[i]->vertices[j].y; if ( game->asteroides[i]->m_contacting ) glColor3f(1,0,0);//red else glColor3f(1,1,1);//white glVertex3f (x,y,0); } glEnd(); glPopMatrix (); } }
void CommunicateSensor::draw() { float x = position[0]; float y = position[1]; float angle = body->GetAngle(); glPushMatrix (); glLineWidth (3.0f); glTranslatef(x,y,0); glRotatef( RADTODEG(angle) , 0, 0, 1 ); glBegin(GL_LINE_LOOP); glColor3f(0,0.5,0);//white for (int j=0; j < 360; j++) { float degInRad = DEGTORAD(j); glVertex2f(cos(degInRad)*radiusMovable,sin(degInRad)*radiusMovable); } glEnd(); glPopMatrix (); if(!obstacleSensorContainer.empty()){ for(auto obstacleSensor : obstacleSensorContainer){ if(obstacleSensor.second->drawable) obstacleSensor.second->draw(); } } }
BOOL CCameraEffectUnit::On(EFFECTPARAM* pParam) { CCameraEffectUnitDesc* pDesc = (CCameraEffectUnitDesc*)m_pEffectUnitDesc; switch( m_CameraEffectUnitType ) { case eCameraEffectUnitType_AngleDist: { CObject* pObject = NULL; if(pDesc->IsDangledToOperator()) // 오퍼레이터 or 타켓 pObject = pParam->m_pOperator; else pObject = pParam->m_pTargetSet[0].pTarget; if( pObject == HEROPETBACKUP ) return TRUE; if(pObject->IsInited() == FALSE) // 케릭터가 존재하지 않으면 return return TRUE; if((pParam->m_dwFlag & EFFECT_FLAG_HEROATTACK) == FALSE) return TRUE; CAMERA->SetCameraPivotObject(pDesc->m_CameraNum,pObject); if(pDesc->m_bRelatedCoordinate) // 상대각도로 변환 { float angleDeg = pDesc->m_InitAngleY+RADTODEG(pObject->GetAngle()); CAMERA->SetTargetAngleY(pDesc->m_CameraNum,angleDeg,0); } CAMERA->SetCurCamera(pDesc->m_CameraNum); } break; case eCameraEffectUnitType_Filter: { int objectnum; TARGETSET* pObject; GetObjectSet(pParam,&pObject,&objectnum); // 대상이 자기자신인 경우에만 필터를 적용시킨다. for(int n=0;n<objectnum;++n) { if( pObject[n].pTarget->GetID() != HEROID ) continue; const BOOL bFade = (m_fFilterFadeTime > 0.f); if( m_bFilterOnlyOne ) CAMERA->DetachCameraFilter( m_dwFilterIndex, bFade, m_fFilterFadeTime ); CCameraFilterObject& cameraFilterObject = CAMERA->AttachCameraFilter( m_dwFilterIndex, !m_bFilterRepeat, bFade, m_fFilterFadeTime, m_dwFilterRemainTime ); m_dwCameraFilterObjectIndex = cameraFilterObject.GetObjectIndex(); } } break; } return TRUE; }
//通过给定的喷射方向destiny确定旋转轴以及旋转角度degree并作旋转,默认喷射方向是(0,1,0) void TransAndRotate(mVector3d pos, mVector3d destiny) { glTranslatef(pos.x, pos.y, pos.z); double axis[3]; //axis为向量destiny与(0,1,0)的叉积 axis[0] = destiny.z; axis[1] = 0; axis[2] = -destiny.x; double degree = RADTODEG(acos(destiny.y/sqrt(destiny.x*destiny.x + destiny.y*destiny.y + destiny.z*destiny.z))); glRotated(degree, axis[0], axis[1], axis[2]); }
void test_updateWheelContactGeom() { const Real rad = .325; WheelContactGeom contact; //terrain SurfaceVector surfs; //flat(surfs); //ramp(surfs); grid(surfs, ResourceDir() + std::string("gridsurfdata.txt") ); //wheel pose HomogeneousTransform HT_wheel_to_world; VecOrient orient = {0,0,0}; //assume WMRSIM_USE_QUATERNION 0 Vec3 pos = {2.5, -1.0, rad}; //adjust height of wheel Real zsurf; surfacesHeight(surfs,pos,zsurf); pos[2] += zsurf; poseToHT(orient,pos,HT_wheel_to_world); //assumes WMRSIM_USE_QUATERNION 0 updateWheelContactGeom(surfs, HT_wheel_to_world, rad, contact ); //print std::cout << "wheel pos = \n"; printVec3(pos,-1,-1); std::cout << "dz = " << contact.dz << std::endl; std::cout << "contact angle (deg)= " << RADTODEG(contact.angle) << std::endl; std::cout << "\nHT_contact_to_wheel=\n"; printHT(contact.HT_wheel,-1,-1); std::cout << "\nHT_contact_to_world=\n"; printHT(contact.HT_world,-1,-1); if (1) { //time it int nw = 4; timeval t0, t1; int n= (int) 1e5; gettimeofday(&t0, NULL); for (int i=0; i<n*nw; i++) { updateWheelContactGeom(surfs, HT_wheel_to_world, rad, contact ); } gettimeofday(&t1, NULL); std::cout << "num wheels: " << nw << std::endl; std::cout << "iterations: " << (Real) n << std::endl; std::cout << "clock (sec): " << tosec(t1)-tosec(t0) << std::endl; } }
void Renderer::DrawQuadTexture(float x, float y, float w, float h,float angle, unsigned int texture_id) { glPushMatrix (); w /= 2.0f; h /= 2.0f; bool texturing_enabled = glIsEnabled(GL_TEXTURE_2D); if(!texturing_enabled) glEnable(GL_TEXTURE_2D); glColor3f (1,1,1); glTranslatef(x,y,0); glRotatef(RADTODEG(angle), 0.0f, 0.0f, 1.0f); glTranslatef(0,0,0); // Bind texture and draw. glBindTexture(GL_TEXTURE_2D, texture_id); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex3f(0 - w, 0 - h,0.1f); glTexCoord2f(1.0f, 1.0f); glVertex3f(0 + w, 0 - h,0.1f); glTexCoord2f(1.0f, 0.0f); glVertex3f(0 + w, 0 + h,0.1f); glTexCoord2f(0.0f, 0.0f); glVertex3f(0 - w, 0 + h,0.1f); /* glTexCoord2f(0.0f, 1.0f); glVertex3f(0+w, 0,0.1f); glTexCoord2f(1.0f, 1.0f); glVertex3f(0 , 0 ,0.1f); glTexCoord2f(1.0f, 0.0f); glVertex3f(0, 0+h,0.1f); glTexCoord2f(0.0f, 0.0f); glVertex3f(0+w, 0+h,0.1f); */ /* glTexCoord2f(0.0f, 1.0f); glVertex3f(1/w, 1/h,0.1f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1*w, 1/h,0.1f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1*w, 1*h,0.1f); glTexCoord2f(0.0f, 0.0f); glVertex3f(1/w, 1*h,0.1f); */ glEnd(); // Disable if was disable. if(!texturing_enabled) glDisable(GL_TEXTURE_2D); glPopMatrix (); }
void Renderer::drawShip () { for (unsigned int i=0; i<game->ships.size(); i++ ) { /* DrawQuadTexture(game->ships[i]->position[0], game->ships[i]->position[1], game->ships[i]->w, game->ships[i]->h, game->ships[i]->fOrientation, game->ships[i]->myID); */ float x = game->ships[i]->position[0]; float y = game->ships[i]->position[1]; float angle = game->ships[i]->fOrientation; int vc = game->ships[i]->vertexCount; glPushMatrix (); glLineWidth (3.0f); glTranslatef(x,y,0); glRotatef( RADTODEG(angle) , 0, 0, 1 ); glBegin (GL_LINE_LOOP); for(int j=0; j<vc; j++) { x = game->ships[i]->vertices[j].x; y = game->ships[i]->vertices[j].y; // glColor3f (0.7,1,1); if ( game->ships[i]->m_contacting ) glColor3f(1,0,0);//red else glColor3f(1,1,1);//white glVertex3f (x,y,0); } glEnd(); glPopMatrix (); // DRAWING MODULE } }
const float& Entity::GetRoll() const { return RADTODEG(this->rotation.z); }
/* * Saves the given parameter to file. * * Returns the number of parameters saved. */ static int SARParmSaveToFileAnyIterate( const char *filename, FILE *fp, const void *p ) { int parms_saved = 0; int type = *(int *)p; /* Version. */ if(type == SAR_PARM_VERSION) { #define PARM_TYPE const sar_parm_version_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "version %i %i %i%s%s\n", pv->major, pv->minor, pv->release, (pv->copyright != NULL) ? " " : "", (pv->copyright != NULL) ? pv->copyright : "" ); parms_saved++; #undef PARM_TYPE } /* Name. */ else if(type == SAR_PARM_NAME) { #define PARM_TYPE const sar_parm_name_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->name != NULL) { fprintf( fp, "name %s\n", pv->name ); parms_saved++; } #undef PARM_TYPE } /* Description. */ else if(type == SAR_PARM_DESCRIPTION) { #define PARM_TYPE const sar_parm_description_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->description != NULL) { fprintf( fp, "description %s\n", pv->description ); parms_saved++; } #undef PARM_TYPE } /* Player model file. */ else if(type == SAR_PARM_PLAYER_MODEL_FILE) { #define PARM_TYPE const sar_parm_player_model_file_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->file != NULL) { fprintf( fp, "player_model_file %s\n", pv->file ); parms_saved++; } #undef PARM_TYPE } /* Weather. */ else if(type == SAR_PARM_WEATHER) { #define PARM_TYPE const sar_parm_weather_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->weather_preset_name != NULL) { fprintf( fp, "weather %s\n", pv->weather_preset_name ); parms_saved++; } #undef PARM_TYPE } /* Time of day. */ else if(type == SAR_PARM_TIME_OF_DAY) { #define PARM_TYPE const sar_parm_time_of_day_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "time_of_day %f\n", pv->tod ); parms_saved++; #undef PARM_TYPE } /* Registered location. */ else if(type == SAR_PARM_REGISTER_LOCATION) { #define PARM_TYPE const sar_parm_register_location_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "register_location %f %f %f %f %f %f%s%s\n", pv->pos.x, pv->pos.y, SFMMetersToFeet(pv->pos.z), RADTODEG(pv->dir.heading), RADTODEG(pv->dir.pitch), RADTODEG(pv->dir.bank), (pv->name != NULL) ? " " : "", (pv->name != NULL) ? pv->name : "" ); parms_saved++; #undef PARM_TYPE } /* Scene GPS. */ else if(type == SAR_PARM_SCENE_GPS) { #define PARM_TYPE const sar_parm_scene_gps_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "scene_gps %f %f %f\n", pv->dms_x_offset, pv->dms_y_offset, pv->planet_radius ); parms_saved++; #undef PARM_TYPE } /* Scene map. */ else if(type == SAR_PARM_SCENE_MAP) { #define PARM_TYPE const sar_parm_scene_map_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "scene_map %f %f%s%s\n", pv->width, pv->height, (pv->file != NULL) ? " " : "", (pv->file != NULL) ? pv->file : "" ); parms_saved++; #undef PARM_TYPE } /* Scene elevation. */ else if(type == SAR_PARM_SCENE_ELEVATION) { #define PARM_TYPE const sar_parm_scene_elevation_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "scene_elevation %f\n", SFMMetersToFeet(pv->elevation) ); parms_saved++; #undef PARM_TYPE } /* Scene CANT. */ else if(type == SAR_PARM_SCENE_CANT) { #define PARM_TYPE const sar_parm_scene_cant_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "scene_cant %f\n", RADTODEG(pv->cant) ); parms_saved++; #undef PARM_TYPE } /* Scene ground flags. */ else if(type == SAR_PARM_SCENE_GROUND_FLAGS) { #define PARM_TYPE const sar_parm_scene_ground_flags_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf(fp, "scene_ground_flags"); if(pv->flags & SAR_SCENE_BASE_FLAG_IS_WATER) fprintf(fp, " is_water"); fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* Scene ground tile. */ else if(type == SAR_PARM_SCENE_GROUND_TILE) { #define PARM_TYPE const sar_parm_scene_ground_tile_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "scene_ground_tile %i %i %f %.2f %.2f %.2f %.2f%s%s\n", pv->tile_width, pv->tile_height, pv->close_range, pv->color.r, pv->color.g, pv->color.b, pv->color.a, (pv->texture_name != NULL) ? " " : "", (pv->texture_name != NULL) ? pv->texture_name : "" ); parms_saved++; #undef PARM_TYPE } /* Texture base directory. */ else if(type == SAR_PARM_TEXTURE_BASE_DIRECTORY) { #define PARM_TYPE const sar_parm_texture_base_directory_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "texture_base_directory%s%s\n", (pv->directory != NULL) ? " " : "", (pv->directory != NULL) ? pv->directory : "" ); parms_saved++; #undef PARM_TYPE } /* Texture load. */ else if(type == SAR_PARM_TEXTURE_LOAD) { #define PARM_TYPE const sar_parm_texture_load_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "texture_load %s %s %f\n", pv->name, pv->file, pv->priority ); parms_saved++; #undef PARM_TYPE } /* Mission scene file. */ else if(type == SAR_PARM_MISSION_SCENE_FILE) { #define PARM_TYPE const sar_parm_mission_scene_file_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_scene_file%s%s\n", (pv->file != NULL) ? " " : "", (pv->file != NULL) ? pv->file : "" ); parms_saved++; #undef PARM_TYPE } /* Mission new objective. */ else if(type == SAR_PARM_MISSION_NEW_OBJECTIVE) { #define PARM_TYPE const sar_parm_mission_new_objective_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf(fp, "mission_objective_new"); switch(pv->objective_type) { case SAR_MISSION_OBJECTIVE_ARRIVE_AT: fprintf(fp, " arrive"); break; case SAR_MISSION_OBJECTIVE_PICK_UP_ARRIVE_AT: fprintf(fp, " pick_up_arrive"); break; case SAR_MISSION_OBJECTIVE_PICK_UP: fprintf(fp, " pick_up"); break; } fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* Mission time left. */ else if(type == SAR_PARM_MISSION_TIME_LEFT) { #define PARM_TYPE const sar_parm_mission_time_left_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_objective_time_left %f\n", pv->time_left ); parms_saved++; #undef PARM_TYPE } /* Mission begin at. */ else if(type == SAR_PARM_MISSION_BEGIN_AT) { #define PARM_TYPE const sar_parm_mission_begin_at_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_begin_at%s%s\n", (pv->name != NULL) ? " " : "", (pv->name != NULL) ? pv->name : "" ); parms_saved++; #undef PARM_TYPE } /* Mission begin at position. */ else if(type == SAR_PARM_MISSION_BEGIN_AT_POS) { #define PARM_TYPE const sar_parm_mission_begin_at_pos_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_begin_at_pos %f %f %f %f %f %f\n", pv->pos.x, pv->pos.y, SFMMetersToFeet(pv->pos.z), RADTODEG(pv->dir.heading), RADTODEG(pv->dir.pitch), RADTODEG(pv->dir.bank) ); parms_saved++; #undef PARM_TYPE } /* Mission arrive at. */ else if(type == SAR_PARM_MISSION_ARRIVE_AT) { #define PARM_TYPE const sar_parm_mission_arrive_at_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_objective_arrive_at%s%s\n", (pv->name != NULL) ? " " : "", (pv->name != NULL) ? pv->name : "" ); parms_saved++; #undef PARM_TYPE } /* Mission message success. */ else if(type == SAR_PARM_MISSION_MESSAGE_SUCCESS) { #define PARM_TYPE const sar_parm_mission_message_success_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_objective_message_success%s%s\n", (pv->message != NULL) ? " " : "", (pv->message != NULL) ? pv->message : "" ); parms_saved++; #undef PARM_TYPE } /* Mission message fail. */ else if(type == SAR_PARM_MISSION_MESSAGE_FAIL) { #define PARM_TYPE const sar_parm_mission_message_fail_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_objective_message_fail%s%s\n", (pv->message != NULL) ? " " : "", (pv->message != NULL) ? pv->message : "" ); parms_saved++; #undef PARM_TYPE } /* Mission humans tally. */ else if(type == SAR_PARM_MISSION_HUMANS_TALLY) { #define PARM_TYPE const sar_parm_mission_humans_tally_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "mission_objective_humans_tally %i %i\n", pv->humans_need_rescue, pv->total_humans ); parms_saved++; #undef PARM_TYPE } /* Mission add intercept. */ else if(type == SAR_PARM_MISSION_ADD_INTERCEPT) { #define PARM_TYPE const sar_parm_mission_add_intercept_struct PARM_TYPE *pv = (PARM_TYPE *)p; switch(pv->ref_code) { case 3: case 2: /* Arrive or begin at location. */ fprintf( fp, "mission_add_intercept %i %f %f\n", pv->ref_code, pv->radius, pv->urgency ); parms_saved++; break; default: /* Standard intercept way point. */ fprintf( fp, "mission_add_intercept %i %f %f %f %f %f\n", pv->ref_code, pv->pos.x, pv->pos.y, pv->pos.z, /* In meters. */ pv->radius, pv->urgency ); parms_saved++; break; } #undef PARM_TYPE } /* Mission log header. */ else if(type == SAR_PARM_MISSION_LOG_HEADER) { #define PARM_TYPE const sar_parm_mission_log_header_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf(fp, "BeginHeader\n"); fprintf(fp, " Version %i %i %i\n", pv->version_major, pv->version_minor, pv->version_release ); if(pv->title != NULL) fprintf(fp, " Title %s\n", pv->title); if(pv->scene_file != NULL) fprintf(fp, " SceneFile %s\n", pv->scene_file); if(pv->player_stats_file != NULL) fprintf(fp, " PlayerStatsFile %s\n", pv->player_stats_file); fprintf(fp, "EndHeader\n"); parms_saved++; #undef PARM_TYPE } /* Mission log event. */ else if(type == SAR_PARM_MISSION_LOG_EVENT) { #define PARM_TYPE const sar_parm_mission_log_event_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "%i %f %f %f %f%c%s\n", pv->event_type, pv->tod, pv->pos.x, pv->pos.y, pv->pos.z, /* In meters. */ (pv->message != NULL) ? ':' : '\0', (pv->message != NULL) ? pv->message : "" ); parms_saved++; #undef PARM_TYPE } /* New object. */ else if(type == SAR_PARM_NEW_OBJECT) { #define PARM_TYPE const sar_parm_new_object_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "new_object %i\n", pv->object_type ); parms_saved++; #undef PARM_TYPE } /* New helipad. */ else if(type == SAR_PARM_NEW_HELIPAD) { #define PARM_TYPE const sar_parm_new_helipad_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->ref_obj_name != NULL) fprintf( fp, "new_helipad %s %f %f %f %s %c %c %c %c %c %s %f %f %f %f %f %f\n", pv->style, pv->length, pv->width, SFMMetersToFeet(pv->recession), (pv->label != NULL) ? pv->label : "_", (pv->flags & SAR_HELIPAD_FLAG_EDGE_LIGHTING) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_FUEL) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_REPAIR) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_DROPOFF) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_RESTART_POINT) ? 'y' : 'n', pv->ref_obj_name, pv->ref_offset.x, pv->ref_offset.y, SFMMetersToFeet(pv->ref_offset.z), RADTODEG(pv->ref_dir.heading), RADTODEG(pv->ref_dir.pitch), RADTODEG(pv->ref_dir.bank) ); else fprintf( fp, "new_helipad %s %f %f %f %s %c %c %c %c %c\n", pv->style, pv->length, pv->width, SFMMetersToFeet(pv->recession), (pv->label != NULL) ? pv->label : "_", (pv->flags & SAR_HELIPAD_FLAG_EDGE_LIGHTING) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_FUEL) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_REPAIR) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_DROPOFF) ? 'y' : 'n', (pv->flags & SAR_HELIPAD_FLAG_RESTART_POINT) ? 'y' : 'n' ); parms_saved++; #undef PARM_TYPE } /* New runway. */ else if(type == SAR_PARM_NEW_RUNWAY) { #define PARM_TYPE const sar_parm_new_runway_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "new_runway %f %f %f %i %i %f %s %s %f %f", pv->range, pv->length, pv->width, pv->surface_type, pv->dashes, pv->edge_light_spacing, (pv->north_label != NULL) ? pv->north_label : "_", (pv->south_label != NULL) ? pv->south_label : "_", pv->north_displaced_threshold, pv->south_displaced_threshold ); if(pv->flags & SAR_RUNWAY_FLAG_THRESHOLDS) fprintf(fp, " thresholds"); if(pv->flags & SAR_RUNWAY_FLAG_BORDERS) fprintf(fp, " borders"); if(pv->flags & SAR_RUNWAY_FLAG_TD_MARKERS) fprintf(fp, " td_markers"); if(pv->flags & SAR_RUNWAY_FLAG_MIDWAY_MARKERS) fprintf(fp, " midway_markers"); if(pv->flags & SAR_RUNWAY_FLAG_NORTH_GS) fprintf(fp, " north_gs"); if(pv->flags & SAR_RUNWAY_FLAG_SOUTH_GS) fprintf(fp, " south_gs"); fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* New human. */ else if(type == SAR_PARM_NEW_HUMAN) { #define PARM_TYPE const sar_parm_new_human_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "new_human %s", pv->type_name ); if(pv->flags & SAR_HUMAN_FLAG_NEED_RESCUE) fprintf(fp, " need_rescue"); if(pv->flags & SAR_HUMAN_FLAG_SIT) fprintf(fp, " sit"); if(pv->flags & SAR_HUMAN_FLAG_SIT_UP) fprintf(fp, " sit_up"); if(pv->flags & SAR_HUMAN_FLAG_SIT_DOWN) fprintf(fp, " sit_down"); if(pv->flags & SAR_HUMAN_FLAG_LYING) fprintf(fp, " lying"); if(pv->flags & SAR_HUMAN_FLAG_ALERT) fprintf(fp, " alert"); if(pv->flags & SAR_HUMAN_FLAG_AWARE) fprintf(fp, " aware"); if(pv->flags & SAR_HUMAN_FLAG_IN_WATER) fprintf(fp, " in_water"); fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* New fire. */ else if(type == SAR_PARM_NEW_FIRE) { #define PARM_TYPE const sar_parm_new_fire_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "new_fire %f %f\n", pv->radius, SFMMetersToFeet(pv->height) ); parms_saved++; #undef PARM_TYPE } /* New smoke. */ else if(type == SAR_PARM_NEW_SMOKE) { #define PARM_TYPE const sar_parm_new_smoke_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "new_smoke %f %f %f %f %f %f %i %ld %i %i\n", pv->offset.x, pv->offset.y, pv->offset.z, /* In meters. */ pv->radius_start, pv->radius_max, pv->radius_rate, pv->hide_at_max, pv->respawn_int, pv->total_units, pv->color_code ); parms_saved++; #undef PARM_TYPE } /* New premodeled object. */ else if(type == SAR_PARM_NEW_PREMODELED) { #define PARM_TYPE const sar_parm_new_premodeled_struct int i; PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "new_premodeled %s", pv->model_type ); for(i = 0; i < pv->argc; i++) fprintf(fp, " %s", pv->argv[i]); fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* Select object by name. */ else if(type == SAR_PARM_SELECT_OBJECT_BY_NAME) { #define PARM_TYPE const sar_parm_select_object_by_name_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->name != NULL) { fprintf( fp, "select_object_by_name %s\n", pv->name ); parms_saved++; } #undef PARM_TYPE } /* Model file. */ else if(type == SAR_PARM_MODEL_FILE) { #define PARM_TYPE const sar_parm_model_file_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->file != NULL) { fprintf( fp, "model_file %s\n", pv->file ); parms_saved++; } #undef PARM_TYPE } /* Range. */ else if(type == SAR_PARM_RANGE) { #define PARM_TYPE const sar_parm_range_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "range %f\n", pv->range ); parms_saved++; #undef PARM_TYPE } /* Range far. */ else if(type == SAR_PARM_RANGE_FAR) { #define PARM_TYPE const sar_parm_range_far_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "range_far %f\n", pv->range_far ); parms_saved++; #undef PARM_TYPE } /* Translate. */ else if(type == SAR_PARM_TRANSLATE) { #define PARM_TYPE const sar_parm_translate_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "translate %f %f %f\n", pv->translate.x, pv->translate.y, SFMMetersToFeet(pv->translate.z) ); parms_saved++; #undef PARM_TYPE } /* Translate random. */ else if(type == SAR_PARM_TRANSLATE_RANDOM) { #define PARM_TYPE const sar_parm_translate_random_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "translate_random %f %f\n", pv->radius_bound, pv->z_bound ); parms_saved++; #undef PARM_TYPE } /* Rotate. */ else if(type == SAR_PARM_ROTATE) { #define PARM_TYPE const sar_parm_rotate_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "rotate %f %f %f\n", RADTODEG(pv->rotate.heading), RADTODEG(pv->rotate.pitch), RADTODEG(pv->rotate.bank) ); parms_saved++; #undef PARM_TYPE } /* No depth test. */ else if(type == SAR_PARM_NO_DEPTH_TEST) { #define PARM_TYPE const sar_parm_no_depth_test_struct /* PARM_TYPE *pv = (PARM_TYPE *)p; */ fprintf( fp, "no_depth_test\n" ); parms_saved++; #undef PARM_TYPE } /* Polygon offset. */ else if(type == SAR_PARM_POLYGON_OFFSET) { #define PARM_TYPE const sar_parm_polygon_offset_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf(fp, "polygon_offset"); if(pv->flags & SAR_OBJ_FLAG_POLYGON_OFFSET_REVERSE) fprintf(fp, " reverse"); if(pv->flags & SAR_OBJ_FLAG_POLYGON_OFFSET_WRITE_DEPTH) fprintf(fp, " write_depth"); fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* Countact bounds spherical. */ else if(type == SAR_PARM_CONTACT_BOUNDS_SPHERICAL) { #define PARM_TYPE const sar_parm_contact_bounds_spherical_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "contact_spherical %f\n", pv->radius ); parms_saved++; #undef PARM_TYPE } /* Countact bounds cylendrical. */ else if(type == SAR_PARM_CONTACT_BOUNDS_CYLENDRICAL) { #define PARM_TYPE const sar_parm_contact_bounds_cylendrical_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "contact_cylendrical %f %f %f\n", pv->radius, pv->height_min, pv->height_max /* In meters. */ ); parms_saved++; #undef PARM_TYPE } /* Countact bounds rectangular. */ else if(type == SAR_PARM_CONTACT_BOUNDS_RECTANGULAR) { #define PARM_TYPE const sar_parm_contact_bounds_rectangular_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "contact_rectangular %f %f %f %f %f %f\n", pv->x_min, pv->x_max, pv->y_min, pv->y_max, pv->z_min, pv->z_max /* In meters. */ ); parms_saved++; #undef PARM_TYPE } /* Ground elevation. */ else if(type == SAR_PARM_GROUND_ELEVATION) { #define PARM_TYPE const sar_parm_ground_elevation_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "ground_elevation %f\n", SFMMetersToFeet(pv->elevation) ); parms_saved++; #undef PARM_TYPE } /* Object name. */ else if(type == SAR_PARM_OBJECT_NAME) { #define PARM_TYPE const sar_parm_object_name_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "object_name%s%s\n", (pv->name != NULL) ? " " : "", (pv->name != NULL) ? pv->name : "" ); parms_saved++; #undef PARM_TYPE } /* Object map description. */ else if(type == SAR_PARM_OBJECT_MAP_DESCRIPTION) { #define PARM_TYPE const sar_parm_object_map_description_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "object_map_description%s%s\n", (pv->description != NULL) ? " " : "", (pv->description != NULL) ? pv->description : "" ); parms_saved++; #undef PARM_TYPE } /* Object fuel. */ else if(type == SAR_PARM_FUEL) { #define PARM_TYPE const sar_parm_fuel_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "fuel %f %f\n", pv->fuel, pv->fuel_max ); parms_saved++; #undef PARM_TYPE } /* Object hit points. */ else if(type == SAR_PARM_HITPOINTS) { #define PARM_TYPE const sar_parm_hitpoints_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "hitpoints %f %f\n", pv->hitpoints, pv->hitpoints_max ); parms_saved++; #undef PARM_TYPE } /* Object engine state. */ else if(type == SAR_PARM_ENGINE_STATE) { #define PARM_TYPE const sar_parm_engine_state_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "engine_state %i\n", pv->state ); parms_saved++; #undef PARM_TYPE } /* Object passengers. */ else if(type == SAR_PARM_PASSENGERS) { #define PARM_TYPE const sar_parm_passengers_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "passengers %i %i\n", pv->passengers, pv->passengers_max ); parms_saved++; #undef PARM_TYPE } /* Runway approach lighting north. */ else if(type == SAR_PARM_RUNWAY_APPROACH_LIGHTING_NORTH) { #define PARM_TYPE const sar_parm_runway_approach_lighting_north_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "runway_approach_lighting_north" ); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_END) fprintf(fp, " end"); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_TRACER) fprintf(fp, " tracer"); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_ALIGN) fprintf(fp, " align"); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_ILS_GLIDE) fprintf(fp, " ils_glide"); fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* Runway approach lighting south. */ else if(type == SAR_PARM_RUNWAY_APPROACH_LIGHTING_SOUTH) { #define PARM_TYPE const sar_parm_runway_approach_lighting_south_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "runway_approach_lighting_south" ); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_END) fprintf(fp, " end"); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_TRACER) fprintf(fp, " tracer"); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_ALIGN) fprintf(fp, " align"); if(pv->flags & SAR_RUNWAY_APPROACH_LIGHTING_ILS_GLIDE) fprintf(fp, " ils_glide"); fputc('\n', fp); parms_saved++; #undef PARM_TYPE } /* Human message enter. */ else if(type == SAR_PARM_HUMAN_MESSAGE_ENTER) { #define PARM_TYPE const sar_parm_human_message_enter_struct PARM_TYPE *pv = (PARM_TYPE *)p; fprintf( fp, "set_human_message_enter%s%s\n", (pv->message != NULL) ? " " : "", (pv->message != NULL) ? pv->message : "" ); parms_saved++; #undef PARM_TYPE } /* Human reference. */ else if(type == SAR_PARM_HUMAN_REFERENCE) { #define PARM_TYPE const sar_parm_human_reference_struct PARM_TYPE *pv = (PARM_TYPE *)p; if(pv->reference_name != NULL) { fprintf(fp, "human_reference %s", pv->reference_name); if(pv->flags & SAR_HUMAN_FLAG_RUN_TOWARDS) fprintf(fp, " run_towards"); if(pv->flags & SAR_HUMAN_FLAG_RUN_AWAY) fprintf(fp, " run_away"); fputc('\n', fp); } parms_saved++; #undef PARM_TYPE } /* Welcome message. */ else if (type == SAR_PARM_WELCOME_MESSAGE) { #define PARM_TYPE const sar_parm_welcome_message_struct PARM_TYPE *pv = (PARM_TYPE *)p; if (pv->message != NULL) { fprintf(fp, "set_welcome_message %s", pv->message); fputc('\n',fp); } parms_saved++; #undef PARM_TYPE } return(parms_saved); }
// performs rotation around a given vector void Matrix4::rotate_axis(const float axis[3], float angle) { transvec(axis[0], axis[1], axis[2]); rot((float) (RADTODEG(angle)), 'x'); transvecinv(axis[0], axis[1], axis[2]); }
static int geo_get_coeff( const surface_t* const sx, const surface_t* const sy, /* Output */ coord_t* const shift, coord_t* const scale, coord_t* const rot, stimage_error_t* const error) { size_t nxxcoeff, nxycoeff, nyxcoeff, nyycoeff; double xxrange = 1.0; double xyrange = 1.0; double xxmaxmin = 1.0; double xymaxmin = 1.0; double yxrange = 1.0; double yyrange = 1.0; double yxmaxmin = 1.0; double yymaxmin = 1.0; double a, b, c, d; assert(sx); assert(sy); assert(shift); assert(scale); assert(rot); assert(sx->coeff); assert(sy->coeff); assert(sx->ncoeff >= 3); assert(sy->ncoeff >= 3); nxxcoeff = nyxcoeff = sx->nxcoeff; nxycoeff = nyycoeff = sy->nycoeff; /* Get the data range */ if (sx->type != surface_type_polynomial) { xxrange = (sx->bbox.max.x - sx->bbox.min.x) / 2.0; xxmaxmin = -(sx->bbox.max.x - sx->bbox.min.x) / 2.0; xyrange = (sx->bbox.max.y - sx->bbox.min.y) / 2.0; xymaxmin = (sx->bbox.max.y - sx->bbox.min.y) / 2.0; } if (sy->type != surface_type_polynomial) { yxrange = (sy->bbox.max.x - sy->bbox.min.x) / 2.0; yxmaxmin = (sy->bbox.max.x - sy->bbox.min.x) / 2.0; yyrange = (sy->bbox.max.y - sy->bbox.min.y) / 2.0; yymaxmin = (sy->bbox.max.y - sy->bbox.min.y) / 2.0; } /* Get the shifts */ shift->x = sx->coeff[0] + \ sx->coeff[1] * xxmaxmin / xxrange + \ sx->coeff[2] * xymaxmin / xyrange; shift->y = sy->coeff[0] + \ sy->coeff[1] * yxmaxmin / yxrange + sx->coeff[2] * yymaxmin / yyrange; /* Get the rotation and scaling parameters */ if (nxxcoeff > 1) { a = sx->coeff[1] / xxrange; } else { a = 0.0; } if (nxycoeff > 1) { b = sx->coeff[nxxcoeff] / xyrange; } else { b = 0.0; } if (nyxcoeff > 1) { c = sx->coeff[1] / yxrange; } else { c = 0.0; } if (nyycoeff > 1) { d = sy->coeff[nyxcoeff] / yyrange; } else { d = 0.0; } scale->x = sqrt(a*a + c*c); scale->y = sqrt(b*b + d*d); if (double_approx_equal(a, 0.0) && double_approx_equal(c, 0.0)) { rot->x = 0.0; } else { rot->x = RADTODEG(atan2(-c, a)); } if (rot->x < 0.0) { rot->x += 360.0; } if (double_approx_equal(b, 0.0) && double_approx_equal(d, 0.0)) { rot->y = 0.0; } else { rot->y = RADTODEG(atan2(b, d)); } if (rot->y < 0.0) { rot->y += 360.0; } return 0; }
/////////////////////////////////////////////////////////////////// // Render sky void SkyManager::RenderSky() { #if CONFIG2_GLES #warning TODO: implement SkyManager::RenderSky for GLES #else // Draw the sky as a small box around the camera position, with depth write enabled. // This will be done before anything else is drawn so we'll be overlapped by everything else. // Note: The coordinates for this were set up through a rather cumbersome trial-and-error // process - there might be a smarter way to do it, but this seems to work. // Do nothing unless SetSkySet was called if (m_SkySet.empty()) return; glDepthMask( GL_FALSE ); pglActiveTextureARB(GL_TEXTURE0_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Translate so we are at the camera in the X and Z directions, but // put the horizon at a fixed height regardless of camera Y const CCamera& camera = g_Renderer.GetViewCamera(); CVector3D pos = camera.m_Orientation.GetTranslation(); glTranslatef( pos.X, m_HorizonHeight, pos.Z ); // Rotate so that the "left" face, which contains the brightest part of each // skymap, is in the direction of the sun from our light environment glRotatef( 90.0f + RADTODEG(g_Renderer.GetLightEnv().GetRotation()), 0.0f, 1.0f, 0.0f ); // Distance to draw the faces at const float D = 2000.0; CShaderProgramPtr shader; CShaderTechniquePtr skytech; if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) { skytech = g_Renderer.GetShaderManager().LoadEffect("sky_simple"); skytech->BeginPass(); shader = skytech->GetShader(); } // Front face (positive Z) if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->BindTexture("baseTex", m_SkyTexture[FRONT]); else m_SkyTexture[FRONT]->Bind(); glBegin( GL_QUADS ); glTexCoord2f( 0, 1 ); glVertex3f( -D, -D, +D ); glTexCoord2f( 1, 1 ); glVertex3f( +D, -D, +D ); glTexCoord2f( 1, 0 ); glVertex3f( +D, +D, +D ); glTexCoord2f( 0, 0 ); glVertex3f( -D, +D, +D ); glEnd(); // Back face (negative Z) if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->BindTexture("baseTex", m_SkyTexture[BACK]); else m_SkyTexture[BACK]->Bind(); glBegin( GL_QUADS ); glTexCoord2f( 1, 1 ); glVertex3f( -D, -D, -D ); glTexCoord2f( 1, 0 ); glVertex3f( -D, +D, -D ); glTexCoord2f( 0, 0 ); glVertex3f( +D, +D, -D ); glTexCoord2f( 0, 1 ); glVertex3f( +D, -D, -D ); glEnd(); // Right face (negative X) if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->BindTexture("baseTex", m_SkyTexture[RIGHT]); else m_SkyTexture[RIGHT]->Bind(); glBegin( GL_QUADS ); glTexCoord2f( 0, 1 ); glVertex3f( -D, -D, -D ); glTexCoord2f( 1, 1 ); glVertex3f( -D, -D, +D ); glTexCoord2f( 1, 0 ); glVertex3f( -D, +D, +D ); glTexCoord2f( 0, 0 ); glVertex3f( -D, +D, -D ); glEnd(); // Left face (positive X) if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->BindTexture("baseTex", m_SkyTexture[LEFT]); else m_SkyTexture[LEFT]->Bind(); glBegin( GL_QUADS ); glTexCoord2f( 1, 1 ); glVertex3f( +D, -D, -D ); glTexCoord2f( 1, 0 ); glVertex3f( +D, +D, -D ); glTexCoord2f( 0, 0 ); glVertex3f( +D, +D, +D ); glTexCoord2f( 0, 1 ); glVertex3f( +D, -D, +D ); glEnd(); // Top face (positive Y) if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->BindTexture("baseTex", m_SkyTexture[TOP]); else m_SkyTexture[TOP]->Bind(); glBegin( GL_QUADS ); glTexCoord2f( 1, 0 ); glVertex3f( +D, +D, -D ); glTexCoord2f( 0, 0 ); glVertex3f( -D, +D, -D ); glTexCoord2f( 0, 1 ); glVertex3f( -D, +D, +D ); glTexCoord2f( 1, 1 ); glVertex3f( +D, +D, +D ); glEnd(); if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) skytech->EndPass(); glPopMatrix(); glDepthMask( GL_TRUE ); #endif }
const float& Entity::GetPitch() const { return RADTODEG(this->rotation.x); }
const float& Entity::GetYaw() const { return RADTODEG(this->rotation.y); }
void MatrixStack::rotate(btQuaternion rot) { btVector3 *axis = &rot.getAxis(); Matrix4 rot_matrix; rot_matrix.rotate(RADTODEG(rot.getAngle()), axis->x(), axis->y(), axis->z()); m_currentMatrix = m_currentMatrix * rot_matrix; }
/* * Called by V3DGLProcessModelExtra() to process a model of type * V3D_MODEL_TYPE_STANDARD. * * Given inputs glres, glinterp, and m are assumed valid. */ static void V3DGLProcessModelStandard( v3d_glresource_struct *glres, v3d_glinterprite_struct *glinterp, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ) { int pn, line_num; const char *line_ptr; void *p; int matrix_level = 0; int texture_binded = FALSE; void *last_p_texture_orient = NULL; int coordinate_axis = V3D_GLCOORDINATE_AXIS_SCIENTIFIC; int flip_winding = FALSE; int pass_normals = V3D_GLPASS_NORMALS_AS_NEEDED; int unitlize_normals = TRUE; int pass_texcoords = V3D_GLPASS_TEXCOORDS_AS_NEEDED; int texture_name_case_sensitive = FALSE; int material_properties = V3D_GLPASS_MATERIAL_PROPERTIES_NEVER; int enable_blending = V3D_GLENABLE_BLENDING_NEVER; int faces = V3D_GLFACES_FRONT_AND_BACK; int blending_enabled = FALSE; int set_blend_func = FALSE; const char *heightfield_base_dir = NULL; const char *texture_base_dir = NULL; int last_begin_ptype = -1; mp_comment_struct *p_comment; mp_translate_struct *p_translate; mp_untranslate_struct *p_untranslate; mp_rotate_struct *p_rotate; mp_unrotate_struct *p_unrotate; mp_point_struct *p_point; mp_line_struct *p_line; mp_line_strip_struct *p_line_strip; mp_line_loop_struct *p_line_loop; mp_triangle_struct *p_triangle; mp_triangle_strip_struct *p_triangle_strip; mp_triangle_fan_struct *p_triangle_fan; mp_quad_struct *p_quad; mp_quad_strip_struct *p_quad_strip; mp_polygon_struct *p_polygon; mp_color_struct *p_color; mp_texture_select_struct *p_texture_select; mp_texture_orient_xy_struct *p_texture_orient_xy; mp_texture_orient_yz_struct *p_texture_orient_yz; mp_texture_orient_xz_struct *p_texture_orient_xz; mp_texture_off_struct *p_texture_off; mp_heightfield_load_struct *p_heightfield_load; /* Get some values GL interpritation structure (if set). */ if(glinterp->flags & V3D_GLFLAG_COORDINATE_AXIS) coordinate_axis = glinterp->coordinate_axis; if(glinterp->flags & V3D_GLFLAG_FLIP_WINDING) flip_winding = glinterp->flip_winding; if(glinterp->flags & V3D_GLFLAG_PASS_NORMALS) pass_normals = glinterp->pass_normals; if(glinterp->flags & V3D_GLFLAG_UNITLIZE_NORMALS) unitlize_normals = glinterp->unitlize_normals; if(glinterp->flags & V3D_GLFLAG_PASS_TEXCOORDS) pass_texcoords = glinterp->pass_texcoords; if(glinterp->flags & V3D_GLFLAG_TEXTURE_NAME_CASE_SENSITIVE) texture_name_case_sensitive = glinterp->texture_name_case_sensitive; if(glinterp->flags & V3D_GLFLAG_MATERIAL_PROPERTIES) material_properties = glinterp->material_properties; if(glinterp->flags & V3D_GLFLAG_FACES) faces = glinterp->faces; if(glinterp->flags & V3D_GLFLAG_ENABLE_BLENDING) enable_blending = glinterp->enable_blending; if(glinterp->flags & V3D_GLFLAG_SET_BLEND_FUNC) set_blend_func = glinterp->set_blend_func; if(glinterp->flags & V3D_GLFLAG_HEIGHTFIELD_BASE_DIR) heightfield_base_dir = glinterp->heightfield_base_dir; if(glinterp->flags & V3D_GLFLAG_TEXTURE_BASE_DIR) texture_base_dir = glinterp->texture_base_dir; /* Iterate through each primitive on the given editor. */ for(pn = 0; pn < m->total_primitives; pn++) { p = m->primitive[pn]; if(p == NULL) continue; /* Call glEnd() if last_begin_ptype does not match the * new primitive type. */ if((last_begin_ptype != V3DMPGetType(p)) && (last_begin_ptype > -1) ) { glEnd(); last_begin_ptype = -1; } /* Handle by primitive type. */ switch(V3DMPGetType(p)) { case V3DMP_TYPE_COMMENT: p_comment = (mp_comment_struct *)p; for(line_num = 0; line_num < p_comment->total_lines; line_num++) { line_ptr = (const char *)p_comment->line[line_num]; if(line_ptr == NULL) continue; if(extra_cb != NULL) extra_cb(m, line_ptr, client_data); } break; case V3DMP_TYPE_TRANSLATE: p_translate = (mp_translate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_TRANSLATIONS) { if(!glinterp->allow_translations) break; } glPushMatrix(); matrix_level++; switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glTranslated( p_translate->x, p_translate->y, p_translate->z ); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glTranslated( p_translate->x, p_translate->z, -p_translate->y ); break; } break; case V3DMP_TYPE_UNTRANSLATE: p_untranslate = (mp_untranslate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_TRANSLATIONS) { if(!glinterp->allow_translations) break; } glPopMatrix(); matrix_level--; break; case V3DMP_TYPE_ROTATE: p_rotate = (mp_rotate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_ROTATIONS) { if(!glinterp->allow_rotations) break; } glPushMatrix(); matrix_level++; switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glRotated( -RADTODEG(p_rotate->heading), 0.0, 0.0, 1.0 ); glRotated( -RADTODEG(p_rotate->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_rotate->bank), 0.0, 1.0, 0.0 ); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glRotated( -RADTODEG(p_rotate->heading), 0.0, 1.0, 0.0 ); glRotated( -RADTODEG(p_rotate->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_rotate->bank), 0.0, 0.0, 1.0 ); break; } break; case V3DMP_TYPE_UNROTATE: p_unrotate = (mp_unrotate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_ROTATIONS) { if(!glinterp->allow_rotations) break; } glPopMatrix(); matrix_level--; break; #define DO_SET_VERTEX_DYNAMIC \ { \ int i; \ mp_vertex_struct *v, *n, *tc; \ mp_vertex_struct *fbn = NULL; /* Fallback normal vector. */ \ \ /* Look for first non-empty fallback normal vector. */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ for(i = 0; i < V_TOTAL; i++) \ { \ n = P_PTR->n[i]; \ if(n != NULL) \ { \ if((n->x != 0.0) || (n->y != 0.0) || (n->z != 0.0)) \ fbn = n; \ } \ } \ } \ \ if(flip_winding) \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if((pass_normals != V3D_GLPASS_NORMALS_NEVER) && (V_TOTAL > 0)) \ { \ n = P_PTR->n[V_TOTAL - 1]; \ if(n != NULL) \ { \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ } \ \ for(i = V_TOTAL - 1; i >= 0; i--) \ { \ v = P_PTR->v[i]; \ n = P_PTR->n[i]; \ tc = P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ else \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if((pass_normals != V3D_GLPASS_NORMALS_NEVER) && (V_TOTAL > 0)) \ { \ n = P_PTR->n[0]; \ if(n != NULL) \ { \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ } \ \ for(i = 0; i < V_TOTAL; i++) \ { \ v = P_PTR->v[i]; \ n = P_PTR->n[i]; \ tc = P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ } #define DO_SET_VERTEX_STATIC \ { \ int i; \ mp_vertex_struct *v, *n, *tc; \ mp_vertex_struct *fbn = NULL; /* Fallback normal vector. */ \ \ /* Look for first non-empty fallback normal vector. */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ for(i = 0; i < V_TOTAL; i++) \ { \ n = &P_PTR->n[i]; \ if(n != NULL) \ { \ if((n->x != 0.0) || (n->y != 0.0) || (n->z != 0.0)) \ fbn = n; \ } \ } \ } \ \ if(flip_winding) \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ n = &P_PTR->n[V_TOTAL - 1]; \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ \ for(i = V_TOTAL - 1; i >= 0; i--) \ { \ v = &P_PTR->v[i]; \ n = &P_PTR->n[i]; \ tc = &P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ else \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ n = &P_PTR->n[0]; \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ \ for(i = 0; i < V_TOTAL; i++) \ { \ v = &P_PTR->v[i]; \ n = &P_PTR->n[i]; \ tc = &P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ } case V3DMP_TYPE_POINT: #define P_PTR p_point #define V_TOTAL V3DMP_POINT_NVERTEX P_PTR = (mp_point_struct *)p; if(last_begin_ptype != V3DMP_TYPE_POINT) glBegin(GL_POINTS); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_POINT; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_LINE: #define P_PTR p_line #define V_TOTAL V3DMP_LINE_NVERTEX P_PTR = (mp_line_struct *)p; if(last_begin_ptype != V3DMP_TYPE_LINE) glBegin(GL_LINES); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_LINE; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_LINE_STRIP: #define P_PTR p_line_strip #define V_TOTAL P_PTR->total P_PTR = (mp_line_strip_struct *)p; glBegin(GL_LINE_STRIP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_LINE_LOOP: #define P_PTR p_line_loop #define V_TOTAL P_PTR->total P_PTR = (mp_line_loop_struct *)p; glBegin(GL_LINE_LOOP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_TRIANGLE: #define P_PTR p_triangle #define V_TOTAL V3DMP_TRIANGLE_NVERTEX P_PTR = (mp_triangle_struct *)p; if(last_begin_ptype != V3DMP_TYPE_TRIANGLE) glBegin(GL_TRIANGLES); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_TRIANGLE; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_TRIANGLE_STRIP: #define P_PTR p_triangle_strip #define V_TOTAL P_PTR->total P_PTR = (mp_triangle_strip_struct *)p; glBegin(GL_TRIANGLE_STRIP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_TRIANGLE_FAN: #define P_PTR p_triangle_fan #define V_TOTAL P_PTR->total P_PTR = (mp_triangle_fan_struct *)p; glBegin(GL_TRIANGLE_FAN); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_QUAD: #define P_PTR p_quad #define V_TOTAL V3DMP_QUAD_NVERTEX P_PTR = (mp_quad_struct *)p; if(last_begin_ptype != V3DMP_TYPE_QUAD) glBegin(GL_QUADS); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_QUAD; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_QUAD_STRIP: #define P_PTR p_quad_strip #define V_TOTAL P_PTR->total P_PTR = (mp_quad_strip_struct *)p; glBegin(GL_QUAD_STRIP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_POLYGON: #define P_PTR p_polygon #define V_TOTAL P_PTR->total P_PTR = (mp_polygon_struct *)p; glBegin(GL_POLYGON); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; #undef DO_SET_VERTEX_STATIC #undef DO_SET_VERTEX_DYNAMIC case V3DMP_TYPE_COLOR: p_color = (mp_color_struct *)p; if(p_color->a < 1.0) { if(enable_blending) { if(!blending_enabled) { glEnable(GL_BLEND); glDisable(GL_ALPHA_TEST); blending_enabled = TRUE; } } if(set_blend_func) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } else { if(enable_blending) { if(blending_enabled) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); blending_enabled = FALSE; } } } /* Set color? */ if(material_properties != V3D_GLPASS_MATERIAL_PROPERTIES_INSTEAD_COLOR) { glColor4d(p_color->r, p_color->g, p_color->b, p_color->a); } /* Set material properties? */ if(material_properties != V3D_GLPASS_MATERIAL_PROPERTIES_NEVER) { GLenum glface; GLfloat glparam[4]; switch(faces) { case V3D_GLFACES_FRONT_AND_BACK: glface = GL_FRONT_AND_BACK; break; case V3D_GLFACES_BACK: glface = GL_BACK; break; default: /* V3D_GLFACES_FRONT */ glface = GL_FRONT; break; } glparam[0] = (GLfloat)(p_color->ambient * p_color->r); glparam[1] = (GLfloat)(p_color->ambient * p_color->g); glparam[2] = (GLfloat)(p_color->ambient * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_AMBIENT, glparam); glparam[0] = (GLfloat)(p_color->diffuse * p_color->r); glparam[1] = (GLfloat)(p_color->diffuse * p_color->g); glparam[2] = (GLfloat)(p_color->diffuse * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_DIFFUSE, glparam); glparam[0] = (GLfloat)(p_color->specular * p_color->r); glparam[1] = (GLfloat)(p_color->specular * p_color->g); glparam[2] = (GLfloat)(p_color->specular * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_SPECULAR, glparam); glparam[0] = (GLfloat)(p_color->shininess * 128.0); glMaterialf(glface, GL_SHININESS, glparam[0]); glparam[0] = (GLfloat)(p_color->emission * p_color->r); glparam[1] = (GLfloat)(p_color->emission * p_color->g); glparam[2] = (GLfloat)(p_color->emission * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_EMISSION, glparam); } break; case V3DMP_TYPE_TEXTURE_SELECT: p_texture_select = (mp_texture_select_struct *)p; if(p_texture_select->name != NULL) { const char *tex_name = (const char *)p_texture_select->name; int tn; v3d_texture_ref_struct *t; /* Previous last_p_texture_orient gets reset when * a new texture is binded. */ last_p_texture_orient = NULL; /* Iterate through each loaded texture on the * gl resources structure. */ for(tn = 0; tn < glres->total_textures; tn++) { t = glres->texture[tn]; if((t == NULL) ? 1 : (t->name == NULL)) continue; if(texture_name_case_sensitive) { if(!strcmp(t->name, tex_name)) break; } else { if(!strcasecmp(t->name, tex_name)) break; } } /* Matched texture? */ if(tn < glres->total_textures) t = glres->texture[tn]; else t = NULL; if(t == NULL) { /* No texture, unbind any existing texture. */ V3DTextureSelect(NULL); texture_binded = FALSE; } else { V3DTextureSelect(t); texture_binded = TRUE; } } break; case V3DMP_TYPE_TEXTURE_ORIENT_XY: p_texture_orient_xy = (mp_texture_orient_xy_struct *)p; if(texture_binded) { last_p_texture_orient = p; } break; case V3DMP_TYPE_TEXTURE_ORIENT_YZ: p_texture_orient_yz = (mp_texture_orient_yz_struct *)p; if(texture_binded) { last_p_texture_orient = p; } break; case V3DMP_TYPE_TEXTURE_ORIENT_XZ: p_texture_orient_xz = (mp_texture_orient_xz_struct *)p; if(texture_binded) { last_p_texture_orient = p; } break; case V3DMP_TYPE_TEXTURE_OFF: p_texture_off = (mp_texture_off_struct *)p; V3DTextureSelect(NULL); texture_binded = FALSE; last_p_texture_orient = NULL; break; case V3DMP_TYPE_HEIGHTFIELD_LOAD: p_heightfield_load = (mp_heightfield_load_struct *)p; if(p_heightfield_load->path != NULL) { int status, widthp, heightp; double x_spacing, y_spacing; const char *cstrptr; v3d_hf_options_struct hfopt; char tmp_path[PATH_MAX + NAME_MAX]; if(ISPATHABSOLUTE(p_heightfield_load->path)) { strncpy(tmp_path, p_heightfield_load->path, PATH_MAX + NAME_MAX); } else if(heightfield_base_dir != NULL) { cstrptr = (const char *)PrefixPaths( heightfield_base_dir, p_heightfield_load->path ); strncpy( tmp_path, (cstrptr == NULL) ? p_heightfield_load->path : cstrptr, PATH_MAX + NAME_MAX ); } else { strncpy(tmp_path, p_heightfield_load->path, PATH_MAX + NAME_MAX); } glPushMatrix(); switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glTranslated( p_heightfield_load->x, p_heightfield_load->y, p_heightfield_load->z ); glRotated( -RADTODEG(p_heightfield_load->heading), 0.0, 0.0, 1.0 ); glRotated( -RADTODEG(p_heightfield_load->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_heightfield_load->bank), 0.0, 1.0, 0.0 ); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glTranslated( p_heightfield_load->x, p_heightfield_load->z, -p_heightfield_load->y ); glRotated( -RADTODEG(p_heightfield_load->heading), 0.0, 1.0, 0.0 ); glRotated( -RADTODEG(p_heightfield_load->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_heightfield_load->bank), 0.0, 0.0, 1.0 ); break; } /* Set up heightfield options. */ hfopt.flags = (V3D_HF_OPT_FLAG_WINDING | V3D_HF_OPT_FLAG_SET_NORMAL | V3D_HF_OPT_FLAG_SET_TEXCOORD ); hfopt.winding = ((flip_winding) ? V3D_HF_WIND_CCW : V3D_HF_WIND_CW ); hfopt.set_normal = ((pass_normals != V3D_GLPASS_NORMALS_NEVER) ? V3D_HF_SET_NORMAL_AVERAGED : V3D_HF_SET_NORMAL_NEVER ); hfopt.set_texcoord = ((pass_texcoords != V3D_GLPASS_TEXCOORDS_NEVER) ? V3D_HF_SET_TEXCOORD_ALWAYS : V3D_HF_SET_TEXCOORD_NEVER ); /* Load heightfield from image file and generate GL * commands. */ status = V3DHFLoadFromFile( tmp_path, p_heightfield_load->x_length, p_heightfield_load->y_length, p_heightfield_load->z_length, &widthp, &heightp, &x_spacing, &y_spacing, NULL, /* No allocated z points. */ NULL, /* GL list not important. */ &hfopt ); glPopMatrix(); } break; } } /* Need to call glEnd() if last_begin_ptype is not -1. */ if(last_begin_ptype > -1) { glEnd(); last_begin_ptype = -1; } /* Pop any extranous matrixes */ while(matrix_level > 0) { glPopMatrix(); matrix_level--; } /* Unbind any textures */ if(texture_binded) V3DTextureSelect(NULL); /* Restore blend state */ if(blending_enabled) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); blending_enabled = FALSE; } }