// 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;	
}
Exemple #2
0
// 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
}
Exemple #5
0
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 ();

    }
}
Exemple #6
0
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;
}
Exemple #8
0
//通过给定的喷射方向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]);
}
Exemple #9
0
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;
	}
}
Exemple #10
0
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 ();
}
Exemple #11
0
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
    }
}
Exemple #12
0
const float& Entity::GetRoll() const
{
	return RADTODEG(this->rotation.z);
}
Exemple #13
0
/*
 *	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);
}
Exemple #14
0
// 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]);
}
Exemple #15
0
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;
}
Exemple #16
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
}
Exemple #17
0
const float& Entity::GetPitch() const
{
	return RADTODEG(this->rotation.x);
}
Exemple #18
0
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;
}
Exemple #20
0
/*
 *      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;
	}
}