Beispiel #1
0
//==========================================================================
//
// 
//
//==========================================================================
void GLSprite::Draw(int pass)
{
	if (pass!=GLPASS_PLAIN && pass != GLPASS_ALL && pass!=GLPASS_TRANSLUCENT) return;

	// Hack to enable bright sprites in faded maps
	uint32 backupfade = Colormap.FadeColor.d;
	if (gl_spritebrightfog && fullbright)
		Colormap.FadeColor = 0;


	bool additivefog = false;
	int rel = extralight*gl_weaponlight;

	if (pass==GLPASS_TRANSLUCENT)
	{
		// The translucent pass requires special setup for the various modes.

		// Brightmaps will only be used when doing regular drawing ops and having no fog
		if (!gl_spritebrightfog && (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE || 
			RenderStyle.BlendOp != STYLEOP_Add))
		{
			gl_RenderState.EnableBrightmap(false);
		}

		gl_SetRenderStyle(RenderStyle, false, 
			// The rest of the needed checks are done inside gl_SetRenderStyle
			trans > 1.f - FLT_EPSILON && gl_usecolorblending && gl_fixedcolormap < CM_FIRSTSPECIALCOLORMAP && actor && 
			fullbright && gltexture && !gltexture->GetTransparent());

		if (hw_styleflags == STYLEHW_NoAlphaTest)
		{
			gl_RenderState.EnableAlphaTest(false);
		}
		else
		{
			gl_RenderState.AlphaFunc(GL_GEQUAL,trans*gl_mask_sprite_threshold);
		}

		if (RenderStyle.BlendOp == STYLEOP_Fuzz)
		{
			float fuzzalpha=0.44f;
			float minalpha=0.1f;

			// fog + fuzz don't work well without some fiddling with the alpha value!
			if (!gl_isBlack(Colormap.FadeColor))
			{
				float xcamera=FIXED2FLOAT(viewx);
				float ycamera=FIXED2FLOAT(viewy);

				float dist=Dist2(xcamera,ycamera, x,y);

				if (!Colormap.FadeColor.a) Colormap.FadeColor.a=clamp<int>(255-lightlevel,60,255);

				// this value was determined by trial and error and is scale dependent!
				float factor=0.05f+exp(-Colormap.FadeColor.a*dist/62500.f);
				fuzzalpha*=factor;
				minalpha*=factor;
			}

			gl_RenderState.AlphaFunc(GL_GEQUAL,minalpha*gl_mask_sprite_threshold);
			gl.Color4f(0.2f,0.2f,0.2f,fuzzalpha);
			additivefog = true;
		}
		else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
		{
			additivefog = true;
		}
	}
	if (RenderStyle.BlendOp!=STYLEOP_Fuzz)
	{
		if (actor)
		{
			lightlevel = gl_SetSpriteLighting(RenderStyle, actor, lightlevel, rel, &Colormap, ThingColor, trans,
							 fullbright || gl_fixedcolormap >= CM_FIRSTSPECIALCOLORMAP, false);
		}
		else if (particle)
		{
			if (gl_light_particles)
			{
				lightlevel = gl_SetSpriteLight(particle, lightlevel, rel, &Colormap, trans, ThingColor);
			}
			else 
			{
				gl_SetColor(lightlevel, rel, &Colormap, trans, ThingColor);
			}
		}
		else return;
	}

	if (gl_isBlack(Colormap.FadeColor)) foglevel=lightlevel;

	if (RenderStyle.Flags & STYLEF_FadeToBlack) 
	{
		Colormap.FadeColor=0;
		additivefog = true;
	}

	if (RenderStyle.Flags & STYLEF_InvertOverlay) 
	{
		Colormap.FadeColor = Colormap.FadeColor.InverseColor();
		additivefog=false;
	}

	gl_SetFog(foglevel, rel, &Colormap, additivefog);

	if (gltexture) gltexture->BindPatch(Colormap.colormap,translation);
	else if (!modelframe) gl_RenderState.EnableTexture(false);

	if (!modelframe)
	{
		// [BB] Billboard stuff
		const bool drawWithXYBillboard = ( !(actor && actor->renderflags & RF_FORCEYBILLBOARD)
		                                   //&& GLRenderer->mViewActor != NULL
		                                   && (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD )) );
		gl_RenderState.Apply();
		gl.Begin(GL_TRIANGLE_STRIP);
		if ( drawWithXYBillboard )
		{
			// Rotate the sprite about the vector starting at the center of the sprite
			// triangle strip and with direction orthogonal to where the player is looking
			// in the x/y plane.
			float xcenter = (x1+x2)*0.5;
			float ycenter = (y1+y2)*0.5;
			float zcenter = (z1+z2)*0.5;
			float angleRad = DEG2RAD(270. - float(GLRenderer->mAngles.Yaw));
			
			Matrix3x4 mat;
			mat.MakeIdentity();
			mat.Translate( xcenter, zcenter, ycenter);
			mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch);
			mat.Translate( -xcenter, -zcenter, -ycenter);
			Vector v1 = mat * Vector(x1,z1,y1);
			Vector v2 = mat * Vector(x2,z1,y2);
			Vector v3 = mat * Vector(x1,z2,y1);
			Vector v4 = mat * Vector(x2,z2,y2);

			if (gltexture)
			{
				gl.TexCoord2f(ul, vt); gl.Vertex3fv(&v1[0]);
				gl.TexCoord2f(ur, vt); gl.Vertex3fv(&v2[0]);
				gl.TexCoord2f(ul, vb); gl.Vertex3fv(&v3[0]);
				gl.TexCoord2f(ur, vb); gl.Vertex3fv(&v4[0]);
			}
			else	// Particle
			{
				gl.Vertex3fv(&v1[0]);
				gl.Vertex3fv(&v2[0]);
				gl.Vertex3fv(&v3[0]);
				gl.Vertex3fv(&v4[0]);
			}

		}
		else
		{
			if (gltexture)
			{
				gl.TexCoord2f(ul, vt); gl.Vertex3f(x1, z1, y1);
				gl.TexCoord2f(ur, vt); gl.Vertex3f(x2, z1, y2);
				gl.TexCoord2f(ul, vb); gl.Vertex3f(x1, z2, y1);
				gl.TexCoord2f(ur, vb); gl.Vertex3f(x2, z2, y2);
			}
			else	// Particle
			{
				gl.Vertex3f(x1, z1, y1);
				gl.Vertex3f(x2, z1, y2);
				gl.Vertex3f(x1, z2, y1);
				gl.Vertex3f(x2, z2, y2);
			}
		}
		gl.End();
	}
	else
	{
		gl_RenderModel(this, Colormap.colormap);
	}

	if (pass==GLPASS_TRANSLUCENT)
	{
		gl_RenderState.EnableBrightmap(true);
		gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		gl_RenderState.BlendEquation(GL_FUNC_ADD);
		gl_RenderState.SetTextureMode(TM_MODULATE);

		// [BB] Restore the alpha test after drawing a smooth particle.
		if (hw_styleflags == STYLEHW_NoAlphaTest)
		{
			gl_RenderState.EnableAlphaTest(true);
		}
		else
		{
			gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold);
		}
	}

	// End of gl_sprite_brightfog hack: restore FadeColor to normalcy
	if (backupfade != Colormap.FadeColor.d)
		Colormap.FadeColor = backupfade;

	gl_RenderState.EnableTexture(true);
}
Beispiel #2
0
/*
===============
UI_DrawPlayerII

A less FOV stretched version for drawing on the main menu
===============
*/
void UI_DrawPlayerII( float x, float y, float w, float h, playerInfo_t *pi, int time ) {
    refdef_t		refdef;
    refEntity_t		legs;
    refEntity_t		torso;
    refEntity_t		head;
    refEntity_t		gun;
    refEntity_t		barrel;
    refEntity_t		flash;
    vec3_t			origin;
    int				renderfx;
    vec3_t			mins = {-16, -16, -24};
    vec3_t			maxs = {16, 16, 32};
    float			len;
    float			xx;

    if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) {
        return;
    }

    // this allows the ui to cache the player model on the main menu
    if (w == 0 || h == 0) {
        return;
    }

    dp_realtime = time;

    if ( pi->pendingWeapon != -1 && dp_realtime > pi->weaponTimer ) {
        pi->weapon = pi->pendingWeapon;
        pi->lastWeapon = pi->pendingWeapon;
        pi->pendingWeapon = -1;
        pi->weaponTimer = 0;
        if( pi->currentWeapon != pi->weapon ) {
            trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL );
        }
    }

    UI_AdjustFrom640( &x, &y, &w, &h );

    y -= jumpHeight;

    memset( &refdef, 0, sizeof( refdef ) );
    memset( &legs, 0, sizeof(legs) );
    memset( &torso, 0, sizeof(torso) );
    memset( &head, 0, sizeof(head) );

    refdef.rdflags = RDF_NOWORLDMODEL;

    AxisClear( refdef.viewaxis );

    refdef.x = x;
    refdef.y = y;
    refdef.width = w;
    refdef.height = h;

    refdef.fov_x = (int)((float)refdef.width / 640.0f * 30.0f);
    xx = refdef.width / tan( refdef.fov_x / 360 * M_PI );
    refdef.fov_y = atan2( refdef.height, xx );
    refdef.fov_y *= ( 360 / (float)M_PI );

    // calculate distance so the player nearly fills the box
    len = 0.7 * ( maxs[2] - mins[2] );
    origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.93 );
    origin[1] = 1.0 * ( mins[1] + maxs[1] );
    origin[2] = -2.7 * ( mins[2] + maxs[2] );

    refdef.time = dp_realtime;

    trap_R_ClearScene();

    // get the rotation information
    UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis );

    // get the animation state (after rotation, to allow feet shuffle)
    UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp,
                        &torso.oldframe, &torso.frame, &torso.backlerp );

    renderfx = RF_LIGHTING_ORIGIN;

    //
    // add the legs
    //
    legs.hModel = pi->legsModel;
    legs.customSkin = pi->legsSkin;

    VectorCopy( origin, legs.origin );

    VectorCopy( origin, legs.lightingOrigin );
    legs.renderfx = renderfx;
    VectorCopy (legs.origin, legs.oldorigin);

    trap_R_AddRefEntityToScene( &legs );
    if (!legs.hModel) {
        return;
    }

    //
    // add the torso
    //
    torso.hModel = pi->torsoModel;
    if (!torso.hModel) {
        return;
    }

    torso.customSkin = pi->torsoSkin;

    VectorCopy( origin, torso.lightingOrigin );

    UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso");

    torso.renderfx = renderfx;

    trap_R_AddRefEntityToScene( &torso );

    //
    // add the head
    //
    head.hModel = pi->headModel;
    if (!head.hModel) {
        return;
    }
    head.customSkin = pi->headSkin;

    VectorCopy( origin, head.lightingOrigin );

    UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head");

    head.renderfx = renderfx;

    trap_R_AddRefEntityToScene( &head );

    //
    // add the gun
    //
    if ( pi->currentWeapon != WP_NONE ) {
        memset( &gun, 0, sizeof(gun) );
        gun.hModel = pi->weaponModel;
        VectorCopy( origin, gun.lightingOrigin );
        UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon");
        gun.renderfx = renderfx;
        trap_R_AddRefEntityToScene( &gun );
    }

    //
    // add the spinning barrel
    //
    if ( pi->realWeapon == WP_MACHINEGUN || pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) {
        vec3_t	angles;

        memset( &barrel, 0, sizeof(barrel) );
        VectorCopy( origin, barrel.lightingOrigin );
        barrel.renderfx = renderfx;

        barrel.hModel = pi->barrelModel;
        angles[YAW] = 0;
        angles[PITCH] = 0;
        angles[ROLL] = UI_MachinegunSpinAngle( pi );
        if( pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) {
            angles[PITCH] = angles[ROLL];
            angles[ROLL] = 0;
        }
        AnglesToAxis( angles, barrel.axis );

        UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel");

        trap_R_AddRefEntityToScene( &barrel );
    }

    //
    // add muzzle flash
    //
    if ( dp_realtime <= pi->muzzleFlashTime ) {
        if ( pi->flashModel ) {
            memset( &flash, 0, sizeof(flash) );
            flash.hModel = pi->flashModel;
            VectorCopy( origin, flash.lightingOrigin );
            UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash");
            flash.renderfx = renderfx;
            trap_R_AddRefEntityToScene( &flash );
        }

        // make a dlight for the flash
        if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) {
            trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0],
                                    pi->flashDlightColor[1], pi->flashDlightColor[2] );
        }
    }

    //
    // add the chat icon
    //
    if ( pi->chat ) {
        UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) );
    }

    //
    // add an accent light
    //
    origin[0] -= 100;	// + = behind, - = in front
    origin[1] += 100;	// + = left, - = right
    origin[2] += 100;	// + = above, - = below
    //trap_R_AddLightToScene( origin, 500, 0.3, 0.2, 0.8 );

    origin[0] += 10;	// + = behind, - = in front
    origin[1] += 80;	// + = left, - = right
    origin[2] += 130;	// + = above, - = below
    trap_R_AddLightToScene( origin, 250, 0.54, 0.89, 0.79 );


    origin[0] -= 50;	// + = behind, - = in front
    origin[1] -= 90;	// + = left, - = right
    origin[2] -= 69;	// + = above, - = below
    trap_R_AddLightToScene( origin, 350, 0.60, 0.03, 0.22 );


    origin[0] -= 100;
    origin[1] -= 100;
    origin[2] -= 100;
    //trap_R_AddLightToScene( origin, 500, 0.8, 0.2, 0.1 );
//	UI_ForceLegsAnim( pi, BOTH_POSE );	// leilei - pose hack
//	UI_ForceTorsoAnim( pi, BOTH_POSE );

    trap_R_RenderScene( &refdef );
}
bool QgsSimpleMarkerSymbolLayerV2::prepareShape()
{
  mPolygon.clear();

  if ( mName == "square" || mName == "rectangle" )
  {
    mPolygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
    return true;
  }
  else if ( mName == "diamond" )
  {
    mPolygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
    << QPointF( 1, 0 ) << QPointF( 0, -1 );
    return true;
  }
  else if ( mName == "pentagon" )
  {
    mPolygon << QPointF( sin( DEG2RAD( 288.0 ) ), - cos( DEG2RAD( 288.0 ) ) )
    << QPointF( sin( DEG2RAD( 216.0 ) ), - cos( DEG2RAD( 216.0 ) ) )
    << QPointF( sin( DEG2RAD( 144.0 ) ), - cos( DEG2RAD( 144.0 ) ) )
    << QPointF( sin( DEG2RAD( 72.0 ) ), - cos( DEG2RAD( 72.0 ) ) )
    << QPointF( 0, -1 );
    return true;
  }
  else if ( mName == "triangle" )
  {
    mPolygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 );
    return true;
  }
  else if ( mName == "equilateral_triangle" )
  {
    mPolygon << QPointF( sin( DEG2RAD( 240.0 ) ), - cos( DEG2RAD( 240.0 ) ) )
    << QPointF( sin( DEG2RAD( 120.0 ) ), - cos( DEG2RAD( 120.0 ) ) )
    << QPointF( 0, -1 );
    return true;
  }
  else if ( mName == "star" )
  {
    double sixth = 1.0 / 3;

    mPolygon << QPointF( 0, -1 )
    << QPointF( -sixth, -sixth )
    << QPointF( -1, -sixth )
    << QPointF( -sixth, 0 )
    << QPointF( -1, 1 )
    << QPointF( 0, + sixth )
    << QPointF( 1, 1 )
    << QPointF( + sixth, 0 )
    << QPointF( 1, -sixth )
    << QPointF( + sixth, -sixth );
    return true;
  }
  else if ( mName == "regular_star" )
  {
    double inner_r = cos( DEG2RAD( 72.0 ) ) / cos( DEG2RAD( 36.0 ) );

    mPolygon << QPointF( inner_r * sin( DEG2RAD( 324.0 ) ), - inner_r * cos( DEG2RAD( 324.0 ) ) )  // 324
    << QPointF( sin( DEG2RAD( 288.0 ) ) , - cos( DEG2RAD( 288 ) ) )    // 288
    << QPointF( inner_r * sin( DEG2RAD( 252.0 ) ), - inner_r * cos( DEG2RAD( 252.0 ) ) )   // 252
    << QPointF( sin( DEG2RAD( 216.0 ) ) , - cos( DEG2RAD( 216.0 ) ) )   // 216
    << QPointF( 0, inner_r )         // 180
    << QPointF( sin( DEG2RAD( 144.0 ) ) , - cos( DEG2RAD( 144.0 ) ) )   // 144
    << QPointF( inner_r * sin( DEG2RAD( 108.0 ) ), - inner_r * cos( DEG2RAD( 108.0 ) ) )   // 108
    << QPointF( sin( DEG2RAD( 72.0 ) ) , - cos( DEG2RAD( 72.0 ) ) )    //  72
    << QPointF( inner_r * sin( DEG2RAD( 36.0 ) ), - inner_r * cos( DEG2RAD( 36.0 ) ) )   //  36
    << QPointF( 0, -1 );          //   0
    return true;
  }
  else if ( mName == "arrow" )
  {
    mPolygon
    << QPointF( 0, -1 )
    << QPointF( 0.5,  -0.5 )
    << QPointF( 0.25, -0.25 )
    << QPointF( 0.25,  1 )
    << QPointF( -0.25,  1 )
    << QPointF( -0.25, -0.5 )
    << QPointF( -0.5,  -0.5 );
    return true;
  }
  else if ( mName == "filled_arrowhead" )
  {
    mPolygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
    return true;
  }

  return false;
}
static QPointF _rotatedOffset( const QPointF& offset, double angle )
{
  angle = DEG2RAD( angle );
  double c = cos( angle ), s = sin( angle );
  return QPointF( offset.x() * c - offset.y() * s, offset.x() * s + offset.y() * c );
}
/*
======================
BOEntity::Draw
======================
*/
void BOEntity::Draw(idDeviceContext *dc) {
	if ( visible ) {
		dc->DrawMaterialRotated( position.x, position.y, width, height, material, color, 1.0f, 1.0f, DEG2RAD(0.f) );
	}
}
Beispiel #6
0
double QgsDistanceArea::computeDistanceBearing(
  const QgsPoint& p1, const QgsPoint& p2,
  double* course1, double* course2 )
{
  if ( p1.x() == p2.x() && p1.y() == p2.y() )
    return 0;

  // ellipsoid
  double a = mSemiMajor;
  double b = mSemiMinor;
  double f = 1 / mInvFlattening;

  double p1_lat = DEG2RAD( p1.y() ), p1_lon = DEG2RAD( p1.x() );
  double p2_lat = DEG2RAD( p2.y() ), p2_lon = DEG2RAD( p2.x() );

  double L = p2_lon - p1_lon;
  double U1 = atan(( 1 - f ) * tan( p1_lat ) );
  double U2 = atan(( 1 - f ) * tan( p2_lat ) );
  double sinU1 = sin( U1 ), cosU1 = cos( U1 );
  double sinU2 = sin( U2 ), cosU2 = cos( U2 );
  double lambda = L;
  double lambdaP = 2 * M_PI;

  double sinLambda = 0;
  double cosLambda = 0;
  double sinSigma = 0;
  double cosSigma = 0;
  double sigma = 0;
  double alpha = 0;
  double cosSqAlpha = 0;
  double cos2SigmaM = 0;
  double C = 0;
  double tu1 = 0;
  double tu2 = 0;

  int iterLimit = 20;
  while ( qAbs( lambda - lambdaP ) > 1e-12 && --iterLimit > 0 )
  {
    sinLambda = sin( lambda );
    cosLambda = cos( lambda );
    tu1 = ( cosU2 * sinLambda );
    tu2 = ( cosU1 * sinU2 - sinU1 * cosU2 * cosLambda );
    sinSigma = sqrt( tu1 * tu1 + tu2 * tu2 );
    cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
    sigma = atan2( sinSigma, cosSigma );
    alpha = asin( cosU1 * cosU2 * sinLambda / sinSigma );
    cosSqAlpha = cos( alpha ) * cos( alpha );
    cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
    C = f / 16 * cosSqAlpha * ( 4 + f * ( 4 - 3 * cosSqAlpha ) );
    lambdaP = lambda;
    lambda = L + ( 1 - C ) * f * sin( alpha ) *
             ( sigma + C * sinSigma * ( cos2SigmaM + C * cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) ) );
  }

  if ( iterLimit == 0 )
    return -1;  // formula failed to converge

  double uSq = cosSqAlpha * ( a * a - b * b ) / ( b * b );
  double A = 1 + uSq / 16384 * ( 4096 + uSq * ( -768 + uSq * ( 320 - 175 * uSq ) ) );
  double B = uSq / 1024 * ( 256 + uSq * ( -128 + uSq * ( 74 - 47 * uSq ) ) );
  double deltaSigma = B * sinSigma * ( cos2SigmaM + B / 4 * ( cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) -
                                       B / 6 * cos2SigmaM * ( -3 + 4 * sinSigma * sinSigma ) * ( -3 + 4 * cos2SigmaM * cos2SigmaM ) ) );
  double s = b * A * ( sigma - deltaSigma );

  if ( course1 )
  {
    *course1 = atan2( tu1, tu2 );
  }
  if ( course2 )
  {
    // PI is added to return azimuth from P2 to P1
    *course2 = atan2( cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda ) + M_PI;
  }

  return s;
}
Beispiel #7
0
static void HandleEntityAdjustment(void)
{
	char		*value;
	vec3_t		origin, newOrigin, angles;
	char		temp[MAX_QPATH];
	float		rotation;

	G_SpawnString("origin", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		if ( sscanf( value, "%f %f %f", &origin[0], &origin[1], &origin[2] ) != 3 ) {
			G_Printf( "HandleEntityAdjustment: failed sscanf on 'origin' (%s)\n", value );
			VectorClear( origin );
		}
	}
	else
	{
		origin[0] = origin[1] = origin[2] = 0.0;
	}

	rotation = DEG2RAD(level.mRotationAdjust);
	newOrigin[0] = origin[0]*cos(rotation) - origin[1]*sin(rotation);
	newOrigin[1] = origin[0]*sin(rotation) + origin[1]*cos(rotation);
	newOrigin[2] = origin[2];
	VectorAdd(newOrigin, level.mOriginAdjust, newOrigin);
	// damn VMs don't handle outputing a float that is compatible with sscanf in all cases
	Com_sprintf(temp, sizeof( temp ), "%0.0f %0.0f %0.0f", newOrigin[0], newOrigin[1], newOrigin[2]);
	AddSpawnField("origin", temp);

	G_SpawnString("angles", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		if ( sscanf( value, "%f %f %f", &angles[0], &angles[1], &angles[2] ) != 3 ) {
			G_Printf( "HandleEntityAdjustment: failed sscanf on 'angles' (%s)\n", value );
			VectorClear( angles );
		}

		angles[YAW] = fmod(angles[YAW] + level.mRotationAdjust, 360.0f);
		// damn VMs don't handle outputing a float that is compatible with sscanf in all cases
		Com_sprintf(temp, sizeof( temp ), "%0.0f %0.0f %0.0f", angles[0], angles[1], angles[2]);
		AddSpawnField("angles", temp);
	}
	else
	{
		G_SpawnString("angle", NOVALUE, &value);
		if (Q_stricmp(value, NOVALUE) != 0)
		{
			angles[YAW] = atof( value );
		}
		else
		{
			angles[YAW] = 0.0;
		}
		angles[YAW] = fmod(angles[YAW] + level.mRotationAdjust, 360.0f);
		Com_sprintf(temp, sizeof( temp ), "%0.0f", angles[YAW]);
		AddSpawnField("angle", temp);
	}

	// RJR experimental code for handling "direction" field of breakable brushes
	// though direction is rarely ever used.
	G_SpawnString("direction", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		if ( sscanf( value, "%f %f %f", &angles[0], &angles[1], &angles[2] ) != 3 ) {
			G_Printf( "HandleEntityAdjustment: failed sscanf on 'direction' (%s)\n", value );
			VectorClear( angles );
		}
	}
	else
	{
		angles[0] = angles[1] = angles[2] = 0.0;
	}
	angles[YAW] = fmod(angles[YAW] + level.mRotationAdjust, 360.0f);
	Com_sprintf(temp, sizeof( temp ), "%0.0f %0.0f %0.0f", angles[0], angles[1], angles[2]);
	AddSpawnField("direction", temp);


	AddSpawnField("BSPInstanceID", level.mTargetAdjust);

	G_SpawnString("targetname", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		Com_sprintf(temp, sizeof( temp ), "%s%s", level.mTargetAdjust, value);
		AddSpawnField("targetname", temp);
	}

	G_SpawnString("target", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		Com_sprintf(temp, sizeof( temp ), "%s%s", level.mTargetAdjust, value);
		AddSpawnField("target", temp);
	}

	G_SpawnString("killtarget", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		Com_sprintf(temp, sizeof( temp ), "%s%s", level.mTargetAdjust, value);
		AddSpawnField("killtarget", temp);
	}

	G_SpawnString("brushparent", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		Com_sprintf(temp, sizeof( temp ), "%s%s", level.mTargetAdjust, value);
		AddSpawnField("brushparent", temp);
	}

	G_SpawnString("brushchild", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		Com_sprintf(temp, sizeof( temp ), "%s%s", level.mTargetAdjust, value);
		AddSpawnField("brushchild", temp);
	}

	G_SpawnString("enemy", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		Com_sprintf(temp, sizeof( temp ), "%s%s", level.mTargetAdjust, value);
		AddSpawnField("enemy", temp);
	}

	G_SpawnString("ICARUSname", NOVALUE, &value);
	if (Q_stricmp(value, NOVALUE) != 0)
	{
		Com_sprintf(temp, sizeof( temp ), "%s%s", level.mTargetAdjust, value);
		AddSpawnField("ICARUSname", temp);
	}
}
Beispiel #8
0
void RBCamera::get_ortho(RBMatrix& out_mat) const
{
	float h = _near_panel*RBMath::tan(DEG2RAD(_fovy));
	out_mat = RBMatrix::get_ortho(0,h*_ratio , 0, h, _near_panel, _far_panel);
}
Beispiel #9
0
/**
 * @brief execute autocruise
 */
void plan_run_AutoCruise()
{
    PositionStateData positionState;

    PositionStateGet(&positionState);
    PathDesiredData pathDesired;
    // re-use pathdesired that was setup correctly in setup stage.
    PathDesiredGet(&pathDesired);

    FlightModeSettingsPositionHoldOffsetData offset;
    FlightModeSettingsPositionHoldOffsetGet(&offset);

    float controlVector[4];
    ManualControlCommandRollGet(&controlVector[0]);
    ManualControlCommandPitchGet(&controlVector[1]);
    ManualControlCommandYawGet(&controlVector[2]);
    controlVector[3] = 0.5f; // dummy, thrust is normalized separately
    normalizeDeadband(controlVector); // return value ignored
    ManualControlCommandThrustGet(&controlVector[3]); // no deadband as we are using thrust for velocity
    controlVector[3] = boundf(controlVector[3], 1e-6f, 1.0f); // bound to above zero, to prevent loss of vector direction

    // normalize old desired movement vector
    float vector[3] = { pathDesired.End.North - hold_position[0],
                        pathDesired.End.East - hold_position[1],
                        pathDesired.End.Down - hold_position[2] };
    float length    = sqrtf(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
    if (length < 1e-9f) {
        length = 1.0f; // should not happen since initialized properly in setup()
    }
    vector[0] /= length;
    vector[1] /= length;
    vector[2] /= length;

    // start position is advanced according to actual movement - in the direction of desired vector only
    // projection using scalar product
    float kp = (positionState.North - hold_position[0]) * vector[0]
               + (positionState.East - hold_position[1]) * vector[1]
               + (positionState.Down - hold_position[2]) * vector[2];
    if (kp > 0.0f) {
        hold_position[0] += kp * vector[0];
        hold_position[1] += kp * vector[1];
        hold_position[2] += kp * vector[2];
    }

    // new angle is equal to old angle plus offset depending on yaw input and time
    // (controlVector is normalized with a deadband, change is zero within deadband)
    float angle = RAD2DEG(atan2f(vector[1], vector[0]));
    float dT    = PIOS_DELTATIME_GetAverageSeconds(&actimeval);
    angle    += 10.0f * controlVector[2] * dT; // TODO magic value could eventually end up in a to be created settings

    // resulting movement vector is scaled by velocity demand in controlvector[3] [0.0-1.0]
    vector[0] = cosf(DEG2RAD(angle)) * offset.Horizontal * controlVector[3];
    vector[1] = sinf(DEG2RAD(angle)) * offset.Horizontal * controlVector[3];
    vector[2] = -controlVector[1] * offset.Vertical * controlVector[3];

    pathDesired.End.North   = hold_position[0] + vector[0];
    pathDesired.End.East    = hold_position[1] + vector[1];
    pathDesired.End.Down    = hold_position[2] + vector[2];
    // start position has the same offset as in position hold
    pathDesired.Start.North = pathDesired.End.North + offset.Horizontal; // in FlyEndPoint the direction of this vector does not matter
    pathDesired.Start.East  = pathDesired.End.East;
    pathDesired.Start.Down  = pathDesired.End.Down;
    PathDesiredSet(&pathDesired);
}
Beispiel #10
0
void plan_run_VelocityRoam()
{
    // float alpha;
    PathDesiredData pathDesired;

    // velocity roam code completely sets pathdesired object. it was not set in setup phase
    memset(&pathDesired, 0, sizeof(PathDesiredData));
    FlightStatusAssistedControlStateOptions assistedControlFlightMode;
    FlightStatusFlightModeOptions flightMode;

    FlightModeSettingsPositionHoldOffsetData offset;
    FlightModeSettingsPositionHoldOffsetGet(&offset);
    FlightStatusAssistedControlStateGet(&assistedControlFlightMode);
    FlightStatusFlightModeGet(&flightMode);
    StabilizationBankData stabSettings;
    StabilizationBankGet(&stabSettings);

    ManualControlCommandData cmd;
    ManualControlCommandGet(&cmd);

    cmd.Roll  = applyExpo(cmd.Roll, stabSettings.StickExpo.Roll);
    cmd.Pitch = applyExpo(cmd.Pitch, stabSettings.StickExpo.Pitch);
    cmd.Yaw   = applyExpo(cmd.Yaw, stabSettings.StickExpo.Yaw);

    bool flagRollPitchHasInput = (fabsf(cmd.Roll) > 0.0f || fabsf(cmd.Pitch) > 0.0f);

    if (!flagRollPitchHasInput) {
        // no movement desired, re-enter positionHold at current start-position
        if (assistedControlFlightMode == FLIGHTSTATUS_ASSISTEDCONTROLSTATE_PRIMARY) {
            // initiate braking and change assisted control flight mode to braking
            if (flightMode == FLIGHTSTATUS_FLIGHTMODE_LAND) {
                // avoid brake then hold sequence to continue descent.
                plan_setup_land_from_velocityroam();
            } else {
                plan_setup_assistedcontrol();
            }
        }
        // otherwise nothing to do in braking/hold modes
    } else {
        PositionStateData positionState;
        PositionStateGet(&positionState);

        // Revert assist control state to primary, which in this case implies
        // we are in roaming state (a GPS vector assisted velocity roam)
        assistedControlFlightMode = FLIGHTSTATUS_ASSISTEDCONTROLSTATE_PRIMARY;

        // Calculate desired velocity in each direction
        float angle;
        AttitudeStateYawGet(&angle);
        angle = DEG2RAD(angle);
        float cos_angle  = cosf(angle);
        float sine_angle = sinf(angle);
        float rotated[2] = {
            -cmd.Pitch * cos_angle - cmd.Roll * sine_angle,
            -cmd.Pitch * sine_angle + cmd.Roll * cos_angle
        };
        // flip pitch to have pitch down (away) point north
        float horizontalVelMax;
        float verticalVelMax;
        VtolPathFollowerSettingsHorizontalVelMaxGet(&horizontalVelMax);
        VtolPathFollowerSettingsVerticalVelMaxGet(&verticalVelMax);
        float velocity_north = rotated[0] * horizontalVelMax;
        float velocity_east  = rotated[1] * horizontalVelMax;
        float velocity_down  = 0.0f;

        if (flightMode == FLIGHTSTATUS_FLIGHTMODE_LAND) {
            FlightModeSettingsLandingVelocityGet(&velocity_down);
        }

        float velocity = velocity_north * velocity_north + velocity_east * velocity_east;
        velocity = sqrtf(velocity);

        // if one stick input (pitch or roll) should we use fly by vector? set arbitrary distance of say 20m after which we
        // expect new stick input
        // if two stick input pilot is fighting wind manually and we use fly by velocity
        // in reality setting velocity desired to zero will fight wind anyway.

        pathDesired.Start.North = positionState.North;
        pathDesired.Start.East  = positionState.East;
        pathDesired.Start.Down  = positionState.Down;
        pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_NORTH] = velocity_north;
        pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_EAST]  = velocity_east;
        pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_VELOCITYVECTOR_DOWN]  = velocity_down;

        pathDesired.End.North = positionState.North;
        pathDesired.End.East  = positionState.East;
        pathDesired.End.Down  = positionState.Down;

        pathDesired.StartingVelocity = velocity;
        pathDesired.EndingVelocity   = velocity;
        pathDesired.Mode = PATHDESIRED_MODE_VELOCITY;
        if (flightMode == FLIGHTSTATUS_FLIGHTMODE_LAND) {
            pathDesired.Mode = PATHDESIRED_MODE_LAND;
            pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_LAND_OPTIONS] = (float)PATHDESIRED_MODEPARAMETER_LAND_OPTION_NONE;
        } else {
            pathDesired.ModeParameters[PATHDESIRED_MODEPARAMETER_VELOCITY_UNUSED] = 0.0f;
        }
        PathDesiredSet(&pathDesired);
        FlightStatusAssistedControlStateSet(&assistedControlFlightMode);
    }
}
Beispiel #11
0
void SetFov(float fov)
{
	g_fov = fov;
	g_fovFactor = 2 * tan(DEG2RAD(g_fov) / 2.f);
}
Beispiel #12
0
//-----------------------------------------------------------------------------
void ARX_MINIMAP_Show(LPDIRECT3DDEVICE7 m_pd3dDevice, long SHOWLEVEL, long flag, long fl2)
{
	float sstartx, sstarty;

	if (!pTexDetect)
	{
		GetTextureFile("Graph\\particles\\flare.bmp");
		char temp[256];
		MakeDir(temp, "Graph\\particles\\flare.bmp");
		pTexDetect = D3DTextr_GetSurfaceContainer(temp);
	}

	//	SHOWLEVEL=8;
	// First Load Minimap TC & DATA if needed
	if (minimap[SHOWLEVEL].tc == NULL)
	{
		ARX_MINIMAP_GetData(SHOWLEVEL);
	}

	if ((minimap[SHOWLEVEL].tc) && (minimap[SHOWLEVEL].tc->m_pddsSurface))
	{
		float startx, starty, casex, casey, ratiooo;
		float mod_x = (float)MAX_BKGX / (float)MINIMAP_MAX_X;
		float mod_z = (float)MAX_BKGZ / (float)MINIMAP_MAX_Z;

		if (flag == 1)
		{


			startx = 0;
			starty = 0;
			casex = (900) / ((float)MINIMAP_MAX_X);
			casey = (900) / ((float)MINIMAP_MAX_Z);
			ratiooo = 900.f / 250.f;

			if (fl2)
			{
				casex = (600) / ((float)MINIMAP_MAX_X);
				casey = (600) / ((float)MINIMAP_MAX_Z);
				ratiooo = 600.f / 250.f;
			}

		}
		else
		{
			startx = (140); 
			starty = (120);
			casex = (250) / ((float)MINIMAP_MAX_X);
			casey = (250) / ((float)MINIMAP_MAX_Z);
			ratiooo = 1.f;
		}

		sstartx = startx;
		sstarty = starty;


		float ofx, ofx2, ofy, ofy2, px, py;
		px = py = 0.f;

		ofx		= mini_offset_x[CURRENTLEVEL];
		ofx2	= minimap[SHOWLEVEL].xratio;
		ofy		= mini_offset_y[CURRENTLEVEL];
		ofy2	= minimap[SHOWLEVEL].yratio;

		if ((SHOWLEVEL == ARX_LEVELS_GetRealNum(CURRENTLEVEL)) || (flag == 2))
		{
			// Computes playerpos
			ofx = mini_offset_x[CURRENTLEVEL];
			ofx2 = minimap[SHOWLEVEL].xratio;
			ofy = mini_offset_y[CURRENTLEVEL];
			ofy2 = minimap[SHOWLEVEL].yratio;
		
			px = startx + ((player.pos.x + ofx - ofx2) * DIV100 * casex
			               + mini_offset_x[CURRENTLEVEL] * ratiooo * mod_x) / mod_x ; //DIV100*2;
			py = starty + ((mapmaxy[SHOWLEVEL] - ofy - ofy2) * DIV100 * casey
			               - (player.pos.z + ofy - ofy2) * DIV100 * casey + mini_offset_y[CURRENTLEVEL] * ratiooo * mod_z) / mod_z ;    //DIV100*2;

			if (flag == 1)
			{
				sstartx = startx;
				sstarty = starty;

				startx = 490.f - px;
				starty = 220.f - py;
				px += startx;
				py += starty;
			}
		}


		D3DTLVERTEX verts[4];
		SETTC(m_pd3dDevice, minimap[SHOWLEVEL].tc);

		for (long k = 0; k < 4; k++)
		{
			verts[k].color = 0xFFFFFFFF;
			verts[k].rhw = 1;
			verts[k].sz = 0.00001f;
		}

		float div = DIV25;
		TextureContainer * tc = minimap[SHOWLEVEL].tc;
		float dw = 1.f / (float)max(tc->m_dwDeviceWidth, tc->m_dwOriginalWidth); 
		float dh = 1.f / (float)max(tc->m_dwDeviceHeight, tc->m_dwOriginalHeight);
		
		float vx2 = 4.f * dw * mod_x;
		float vy2 = 4.f * dh * mod_z;

		float _px;
		RECT boundaries;
		float MOD20, MOD20DIV, divXratio, divYratio;

		boundaries.bottom = boundaries.left = boundaries.right = boundaries.top = 0;
		MOD20 = MOD20DIV = divXratio = divYratio = 0.f;

		if (flag != 2)
		{

			if (flag == 1)
			{
				MOD20 = 20.f * Xratio;
				MOD20DIV = 1.f / (MOD20);
				//@PERF do if(fl2){}else{} to make 4 and not 8 flot op if fl2.

				ARX_CHECK_LONG((360 + MOD20)*Xratio);
				ARX_CHECK_LONG((555 - MOD20)*Xratio);
				ARX_CHECK_LONG((85 + MOD20)*Yratio);
				ARX_CHECK_LONG((355 - MOD20)*Yratio);

				//CAST
				boundaries.left		=	ARX_CLEAN_WARN_CAST_LONG((360 + MOD20) * Xratio);
				boundaries.right	=	ARX_CLEAN_WARN_CAST_LONG((555 - MOD20) * Xratio);
				boundaries.top		=	ARX_CLEAN_WARN_CAST_LONG((85 + MOD20) * Yratio);
				boundaries.bottom	=	ARX_CLEAN_WARN_CAST_LONG((355 - MOD20) * Yratio);

				if (fl2)
				{
					//CHECK (DEBUG)
					ARX_CHECK_LONG((390 + MOD20)*Xratio);
					ARX_CHECK_LONG((590 - MOD20)*Xratio);
					ARX_CHECK_LONG((135 + MOD20)*Yratio);
					ARX_CHECK_LONG((295 - MOD20)*Yratio);

					//CAST
					boundaries.left		=	ARX_CLEAN_WARN_CAST_LONG((390 + MOD20) * Xratio);
					boundaries.right	=	ARX_CLEAN_WARN_CAST_LONG((590 - MOD20) * Xratio);
					boundaries.top		=	ARX_CLEAN_WARN_CAST_LONG((135 + MOD20) * Yratio);
					boundaries.bottom	=	ARX_CLEAN_WARN_CAST_LONG((295 - MOD20) * Yratio);
				}
			}

			SETALPHABLEND(m_pd3dDevice, TRUE);
			m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,  D3DBLEND_ZERO);
			m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR);
			m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS);
			SETTEXTUREWRAPMODE(m_pd3dDevice, D3DTADDRESS_CLAMP);

			if (fl2)
			{
				m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,  D3DBLEND_ONE);
				m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR);
			}
		}
		else
		{
			divXratio = 1.f / Xratio;
			divYratio = 1.f / Yratio;
		}

		for (long j = -2; j < MINIMAP_MAX_Z + 2; j++)
		{
			for (long i = -2; i < MINIMAP_MAX_X + 2; i++)
			{
				float vx, vy, vxx, vyy;
				vxx = ((float)i * (float)ACTIVEBKG->Xdiv * mod_x);
				vyy = ((float)j * (float)ACTIVEBKG->Zdiv * mod_z);
				vx = (vxx * div) * dw;
				vy = (vyy * div) * dh;

				long okay = 1;
				float posx = (startx + i * casex) * Xratio;
				float posy = (starty + j * casey) * Yratio;

				if (flag == 1)
				{

					if	((posx < 360 * Xratio)
					        ||	(posx > 555 * Xratio)
					        ||	(posy < 85 * Yratio)
					        ||	(posy > 355 * Yratio))
						okay = 0;

					if (fl2)
					{
						okay = 1;

						if	((posx < 390 * Xratio)
						        ||	(posx > 590 * Xratio)
						        ||	(posy < 135 * Yratio)
						        ||	(posy > 295 * Yratio))
							okay = 0;
					}

				}
				else
				{
					if ((posx > 345 * Xratio)
					        ||	(posy > 290 * Yratio))
						okay = 0;
				}

				if (okay)
				{
					if ((flag == 2)
					        && (i >= 0) && (i < MINIMAP_MAX_X)
					        && (j >= 0) && (j < MINIMAP_MAX_Z))
					{
						float d = Distance2D(posx * divXratio + casex * DIV2, posy * divYratio /*-casey * 2 * Yratio*/, px, py);

						if (d <= 6.f)
						{
							long r;
							float vv = (6 - d) * DIV6;

							if (vv >= 0.5f)
								vv = 1.f;
							else if (vv > 0.f)
								vv = vv * 2.f;
							else
								vv = 0.f;

							F2L((float)(vv * 255.f), &r);


							long ucLevel =  __max(r, minimap[SHOWLEVEL].revealed[i][j]);
							ARX_CHECK_UCHAR(ucLevel);

							minimap[SHOWLEVEL].revealed[i][j] = ARX_CLEAN_WARN_CAST_UCHAR(ucLevel);


						}
					}

					if (!FOR_EXTERNAL_PEOPLE)
					{
						if ((i >= 0) && (i < MINIMAP_MAX_X)
						        &&	(j >= 0) && (j < MINIMAP_MAX_Z))
						{
							minimap[SHOWLEVEL].revealed[i][j] = 255;
						}
					}

					verts[3].sx = verts[0].sx = (posx);
					verts[1].sy = verts[0].sy = (posy);
					verts[2].sx = verts[1].sx = posx + (casex * Xratio);
					verts[3].sy = verts[2].sy = posy + (casey * Yratio);

					verts[3].tu = verts[0].tu = vx;
					verts[1].tv = verts[0].tv = vy;
					verts[2].tu = verts[1].tu = vx + vx2;
					verts[3].tv = verts[2].tv = vy + vy2;

					if (flag != 2)
					{
						float v;
						float oo = 0.f;

						if ((i < 0) || (i >= MINIMAP_MAX_X) || (j < 0) || (j >= MINIMAP_MAX_Z)) v = 0;
						else v = ((float)minimap[SHOWLEVEL].revealed[i][j]) * DIV255;

						if (flag == 1)
						{
							long vert = 0;
							_px = verts[vert].sx - boundaries.left;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.right - verts[vert].sx;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = verts[vert].sy - boundaries.top;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.bottom - verts[vert].sy;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;
						}

						if (fl2) verts[0].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
						else
							verts[0].color = D3DRGB(v, v, v);

						oo += v;

						if ((i + 1 < 0) || (i + 1 >= MINIMAP_MAX_X) || (j < 0) || (j >= MINIMAP_MAX_Z)) v = 0;
						else v = ((float)minimap[SHOWLEVEL].revealed[__min(i+1, MINIMAP_MAX_X-1)][j]) * DIV255;

						if (flag == 1)
						{
							long vert = 1;
							_px = verts[vert].sx - boundaries.left;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.right - verts[vert].sx;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = verts[vert].sy - boundaries.top;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.bottom - verts[vert].sy;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;
						}

						if (fl2) verts[1].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
						else
							verts[1].color = D3DRGB(v, v, v);

						oo += v;

						if ((i + 1 < 0) || (i + 1 >= MINIMAP_MAX_X) || (j + 1 < 0) || (j + 1 >= MINIMAP_MAX_Z)) v = 0;
						else v = ((float)minimap[SHOWLEVEL].revealed[__min(i+1, MINIMAP_MAX_X-1)][__min(j+1, MINIMAP_MAX_Z-1)]) * DIV255;

						if (flag == 1)
						{
							long vert = 2;
							_px = verts[vert].sx - boundaries.left;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.right - verts[vert].sx;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = verts[vert].sy - boundaries.top;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.bottom - verts[vert].sy;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;
						}
						

						if (fl2) verts[2].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
						else
							verts[2].color = D3DRGB(v, v, v);

						oo += v;

						if ((i < 0) || (i >= MINIMAP_MAX_X) || (j + 1 < 0) || (j + 1 >= MINIMAP_MAX_Z)) v = 0;
						else v = ((float)minimap[SHOWLEVEL].revealed[i][__min(j+1, MINIMAP_MAX_Z-1)]) * DIV255;

						if (flag == 1)
						{
							long vert = 3;
							_px = verts[vert].sx - boundaries.left;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.right - verts[vert].sx;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = verts[vert].sy - boundaries.top;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;

							_px = boundaries.bottom - verts[vert].sy;

							if (_px < 0.f) v = 0.f;
							else if (_px < MOD20) v *= _px * MOD20DIV;
						}

						if (fl2) verts[3].color = D3DRGB(v * DIV2, v * DIV2, v * DIV2);
						else
							verts[3].color = D3DRGB(v, v, v);

						oo += v;

						if (oo > 0.f)
						{
							if (fl2)
							{
								verts[0].sx += DECALX * Xratio;
								verts[0].sy += DECALY * Yratio;
								verts[1].sx += DECALX * Xratio;
								verts[1].sy += DECALY * Yratio;
								verts[2].sx += DECALX * Xratio;
								verts[2].sy += DECALY * Yratio;
								verts[3].sx += DECALX * Xratio;
								verts[3].sy += DECALY * Yratio;
							}

							EERIEDRAWPRIM(GDevice, D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX | D3DFVF_DIFFUSE, verts, 4, 0);
						}
					}
				}
			}
		}

		if (flag != 2)
		{
			m_pd3dDevice->SetTextureStageState(0, D3DTSS_ADDRESS , D3DTADDRESS_WRAP);
			m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);

			SETALPHABLEND(m_pd3dDevice, FALSE);

			if ((SHOWLEVEL == ARX_LEVELS_GetRealNum(CURRENTLEVEL)))
			{
				// Now Draws Playerpos/angle
				verts[0].color = 0xFFFF0000;
				verts[1].color = 0xFFFF0000;
				verts[2].color = 0xFFFF0000;
				float val;

				if (flag == 1) val = 6.f;
				else val = 3.f;

				float rx = 0.f;
				float ry = -val * 1.8f;
				float rx2 = -val * DIV2;
				float ry2 = val;
				float rx3 = val * DIV2;
				float ry3 = val;

				float angle = DEG2RAD(player.angle.b);
				float ca = EEcos(angle);
				float sa = EEsin(angle);

				verts[0].sx = (px + rx2 * ca + ry2 * sa) * Xratio;
				verts[0].sy = (py + ry2 * ca - rx2 * sa) * Yratio;
				verts[1].sx = (px + rx * ca + ry * sa) * Xratio;
				verts[1].sy = (py + ry * ca - rx * sa) * Yratio;
				verts[2].sx = (px + rx3 * ca + ry3 * sa) * Xratio;
				verts[2].sy = (py + ry3 * ca - rx3 * sa) * Yratio;

				SETTC(GDevice, NULL);

				if (fl2)
				{
					SETALPHABLEND(m_pd3dDevice, TRUE);
					verts[0].sx += DECALX * Xratio;
					verts[0].sy += DECALY * Yratio;
					verts[1].sx += DECALX * Xratio;
					verts[1].sy += DECALY * Yratio;
					verts[2].sx += DECALX * Xratio;
					verts[2].sy += DECALY * Yratio;
				}

				EERIEDRAWPRIM(GDevice, D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX | D3DFVF_DIFFUSE, verts, 3, 0);

				if (fl2) SETALPHABLEND(m_pd3dDevice, FALSE);
			}
		}

		// tsu
		for (long lnpc = 1; lnpc < inter.nbmax; lnpc++)
		{
			if ((inter.iobj[lnpc] != NULL) && (inter.iobj[lnpc]->ioflags & IO_NPC))
			{
				if (inter.iobj[lnpc]->_npcdata->life > 0.f)
					if (!((inter.iobj[lnpc]->GameFlags & GFLAG_MEGAHIDE) ||
					        (inter.iobj[lnpc]->show == SHOW_FLAG_MEGAHIDE))
					        && (inter.iobj[lnpc]->show == SHOW_FLAG_IN_SCENE))
						if (!(inter.iobj[lnpc]->show == SHOW_FLAG_HIDDEN))
							if (inter.iobj[lnpc]->_npcdata->fDetect >= 0)
							{
								if (player.Full_Skill_Etheral_Link >= inter.iobj[lnpc]->_npcdata->fDetect)
								{
									float fpx;
									float fpy;
								
									fpx = sstartx + ((inter.iobj[lnpc]->pos.x - 100 + ofx - ofx2) * DIV100 * casex
									                 + mini_offset_x[CURRENTLEVEL] * ratiooo * mod_x) / mod_x; 
									fpy = sstarty + ((mapmaxy[SHOWLEVEL] - ofy - ofy2) * DIV100 * casey
									                 - (inter.iobj[lnpc]->pos.z + 200 + ofy - ofy2) * DIV100 * casey + mini_offset_y[CURRENTLEVEL] * ratiooo * mod_z) / mod_z; 

									if (flag == 1)
									{

										fpx = startx + ((inter.iobj[lnpc]->pos.x - 100 + ofx - ofx2) * DIV100 * casex
										                + mini_offset_x[CURRENTLEVEL] * ratiooo * mod_x) / mod_x; 
										fpy = starty + ((mapmaxy[SHOWLEVEL] - ofy - ofy2) * DIV100 * casey
										                - (inter.iobj[lnpc]->pos.z + 200 + ofy - ofy2) * DIV100 * casey + mini_offset_y[CURRENTLEVEL] * ratiooo * mod_z) / mod_z; 


									}

									float d = Distance2D(player.pos.x, player.pos.z, inter.iobj[lnpc]->pos.x, inter.iobj[lnpc]->pos.z);

		
									if ((d <= 800) && (fabs(inter.iobj[0]->pos.y - inter.iobj[lnpc]->pos.y) < 250.f))
									{
										float col = 1.f;

										if (d > 600.f)
										{
											col = 1.f - (d - 600.f) * DIV200;
										}

										if (!fl2)
										{
											SETALPHABLEND(m_pd3dDevice, true);
											m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,  D3DBLEND_ONE);
											m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE);
										}
										else
											SETALPHABLEND(m_pd3dDevice, true);

										if (fl2)
										{
											fpx += DECALX * Xratio;
											fpy += (DECALY + 15) * Yratio;
										}

										fpx *= Xratio;
										fpy *= Yratio;
										EERIEDrawBitmap(GDevice, fpx, fpy,
										                5.f * ratiooo, 5.f * ratiooo, 0, pTexDetect, D3DRGB(col, 0, 0));

										if (!fl2)
											SETALPHABLEND(m_pd3dDevice, false);
									}
								}
							}
			}
		}

		if (flag == 0)
			for (long i = 0; i < Nb_Mapmarkers; i++)
			{
				if (Mapmarkers[i].lvl == SHOWLEVEL + 1)
				{
					float pos_x = Mapmarkers[i].x * 8 * ratiooo * ACTIVEBKG->Xmul * casex + startx;
					float pos_y = Mapmarkers[i].y * 8 * ratiooo * ACTIVEBKG->Zmul * casey + starty;
					float size = 5.f * ratiooo;
					verts[0].color = 0xFFFF0000;
					verts[1].color = 0xFFFF0000;
					verts[2].color = 0xFFFF0000;
					verts[3].color = 0xFFFF0000;
					verts[0].sx = (pos_x - size) * Xratio;
					verts[0].sy = (pos_y - size) * Yratio;
					verts[1].sx = (pos_x + size) * Xratio;
					verts[1].sy = (pos_y - size) * Yratio;
					verts[2].sx = (pos_x + size) * Xratio;
					verts[2].sy = (pos_y + size) * Yratio;
					verts[3].sx = (pos_x - size) * Xratio;
					verts[3].sy = (pos_y + size) * Yratio;
					verts[0].tu = 0.f;
					verts[0].tv = 0.f;
					verts[1].tu = 1.f;
					verts[1].tv = 0.f;
					verts[2].tu = 1.f;
					verts[2].tv = 1.f;
					verts[3].tu = 0.f;
					verts[3].tv = 1.f;

					if ((!fl2)
					        && (MouseInRect(verts[0].sx, verts[0].sy, verts[2].sx, verts[2].sy)))
					{
						if (!Mapmarkers[i].tstring)
						{
							_TCHAR output[4096];
							MakeLocalised(Mapmarkers[i].string, output, 4096, 0);
							Mapmarkers[i].tstring = (_TCHAR *)malloc((_tcslen(output) + 1) * sizeof(_TCHAR));
							ZeroMemory(Mapmarkers[i].tstring, (_tcslen(output) + 1)*sizeof(_TCHAR));
							_tcscpy(Mapmarkers[i].tstring, output);
						}

						if (Mapmarkers[i].tstring)
						{
							RECT rRect, bRect;
							SetRect(&bRect	, (140),	(290)
							        , (140 + 205),	(358));

							float fLeft		= (bRect.left) * Xratio ;
							float fRight	= (bRect.right) * Xratio ;
							float fTop		= (bRect.top) * Yratio ;
							float fBottom	= (bRect.bottom) * Yratio ;
							ARX_CHECK_INT(fLeft);
							ARX_CHECK_INT(fRight);
							ARX_CHECK_INT(fTop);
							ARX_CHECK_INT(fBottom);

							SetRect(&rRect
							        , ARX_CLEAN_WARN_CAST_INT(fLeft)
							        , ARX_CLEAN_WARN_CAST_INT(fTop)
							        , ARX_CLEAN_WARN_CAST_INT(fRight)
							        , ARX_CLEAN_WARN_CAST_INT(fBottom));


							long lLengthDraw = ARX_UNICODE_ForceFormattingInRect(
							                       hFontInGameNote, Mapmarkers[i].tstring, 0, rRect);

							danaeApp.DANAEEndRender();
							_TCHAR	Page_Buffer[256];
							_tcsncpy(Page_Buffer, Mapmarkers[i].tstring, lLengthDraw);
							Page_Buffer[lLengthDraw] = _T('\0');

							DrawBookTextInRect(ARX_CLEAN_WARN_CAST_FLOAT(bRect.left), ARX_CLEAN_WARN_CAST_FLOAT(bRect.top),
							                   ARX_CLEAN_WARN_CAST_FLOAT(bRect.right), ARX_CLEAN_WARN_CAST_FLOAT(bRect.bottom),
							                   Page_Buffer, 0, 0x00FF00FF,
							                   hFontInGameNote);


							danaeApp.DANAEStartRender();
						}
					}

					if (MapMarkerTc == NULL)
					{
						MapMarkerTc = MakeTCFromFile("Graph\\interface\\icons\\mapmarker.bmp");
					}

					SETTC(GDevice, MapMarkerTc);

					if (fl2)
					{
						verts[0].sx += DECALX * Xratio;
						verts[0].sy += DECALY * Yratio;
						verts[1].sx += DECALX * Xratio;
						verts[1].sy += DECALY * Yratio;
						verts[2].sx += DECALX * Xratio;
						verts[2].sy += DECALY * Yratio;
						verts[3].sx += DECALX * Xratio;
						verts[3].sy += DECALY * Yratio;
					}

					EERIEDRAWPRIM(GDevice, D3DPT_TRIANGLEFAN, D3DFVF_TLVERTEX | D3DFVF_DIFFUSE, verts, 4, 0);
				}
			}

	}
}
Beispiel #13
0
void SpaceStationType::OnSetupComplete()
{
	// Since the model contains (almost) all of the docking information we have to extract that
	// and then generate any additional locators and information the station will need from it.

	// First we gather the MatrixTransforms that contain the location and orientation of the docking
	// locators/waypoints. We store some information within the name of these which needs parsing too.

	// Next we build the additional information required for docking ships with SPACE stations
	// on autopilot - this is the only option for docking with SPACE stations currently.
	// This mostly means offsetting from one locator to create the next in the sequence.

	// ground stations have a "special-f*****g-case" 0 stage launch process
	shipLaunchStage = ((SURFACE==dockMethod) ? 0 : 3);

	// gather the tags
	SceneGraph::Model::TVecMT entrance_mts;
	SceneGraph::Model::TVecMT locator_mts;
	SceneGraph::Model::TVecMT exit_mts;
	model->FindTagsByStartOfName("entrance_", entrance_mts);
	model->FindTagsByStartOfName("loc_", locator_mts);
	model->FindTagsByStartOfName("exit_", exit_mts);

	Output("%s has:\n %lu entrances,\n %lu pads,\n %lu exits\n", modelName.c_str(), entrance_mts.size(), locator_mts.size(), exit_mts.size());

	// Add the partially initialised ports
	for (auto apprIter : entrance_mts)
	{
		int portId;
		PiVerify(1 == sscanf(apprIter->GetName().c_str(), "entrance_port%d", &portId));
		PiVerify(portId>0);

		SPort new_port;
		new_port.portId = portId;
		new_port.name = apprIter->GetName();
		if(SURFACE==dockMethod) {
			const vector3f offDir = apprIter->GetTransform().Up().Normalized();
			new_port.m_approach[1] = apprIter->GetTransform();
			new_port.m_approach[1].SetTranslate( apprIter->GetTransform().GetTranslate() + (offDir * 500.0f) );
		} else {
			const vector3f offDir = -apprIter->GetTransform().Back().Normalized();
			new_port.m_approach[1] = apprIter->GetTransform();
			new_port.m_approach[1].SetTranslate( apprIter->GetTransform().GetTranslate() + (offDir * 1500.0f) );
		}
		new_port.m_approach[2] = apprIter->GetTransform();
		m_ports.push_back( new_port );
	}

	int bay=0;
	for (auto locIter : locator_mts)
	{
		int bayStr, portId;
		int minSize, maxSize;
		char padname[8];
		const matrix4x4f &locTransform = locIter->GetTransform();

		++bay;

		// eg:loc_A001_p01_s0_500_b01
		PiVerify(5 == sscanf(locIter->GetName().c_str(), "loc_%4s_p%d_s%d_%d_b%d", &padname[0], &portId, &minSize, &maxSize, &bayStr));
		PiVerify(bay>0 && portId>0);

		// find the port and setup the rest of it's information
		bool bFoundPort = false;
		matrix4x4f approach1(0.0);
		matrix4x4f approach2(0.0);
		for(auto &rPort : m_ports) {
			if(rPort.portId == portId) {
				rPort.minShipSize = std::min(minSize,rPort.minShipSize);
				rPort.maxShipSize = std::max(maxSize,rPort.maxShipSize);
				rPort.bayIDs.push_back( std::make_pair(bay-1, padname) );
				bFoundPort = true;
				approach1 = rPort.m_approach[1];
				approach2 = rPort.m_approach[2];
				break;
			}
		}
		assert(bFoundPort);

		// now build the docking/leaving waypoints
		if( SURFACE == dockMethod )
		{
			// ground stations don't have leaving waypoints.
			m_portPaths[bay].m_docking[2] = locTransform; // final (docked)
			numDockingStages = 2;
			numUndockStages = 1;
		}
		else
		{
			struct TPointLine
			{
				// for reference: http://paulbourke.net/geometry/pointlineplane/
				static bool ClosestPointOnLine( const vector3f &Point, const vector3f &LineStart, const vector3f &LineEnd, vector3f &Intersection )
				{
					const float LineMag = ( LineStart - LineEnd ).Length();

					const float U = ( ( ( Point.x - LineStart.x ) * ( LineEnd.x - LineStart.x ) ) +
									(   ( Point.y - LineStart.y ) * ( LineEnd.y - LineStart.y ) ) +
									(   ( Point.z - LineStart.z ) * ( LineEnd.z - LineStart.z ) ) ) /
									( LineMag * LineMag );

					if( U < 0.0f || U > 1.0f )
						return false;   // closest point does not fall within the line segment

					Intersection.x = LineStart.x + U * ( LineEnd.x - LineStart.x );
					Intersection.y = LineStart.y + U * ( LineEnd.y - LineStart.y );
					Intersection.z = LineStart.z + U * ( LineEnd.z - LineStart.z );

					return true;
				}
			};

			// create the docking locators
			// start
			m_portPaths[bay].m_docking[2] = approach2;
			m_portPaths[bay].m_docking[2].SetRotationOnly( locTransform.GetOrient() );
			// above the pad
			vector3f intersectionPos(0.0f);
			const vector3f approach1Pos = approach1.GetTranslate();
			const vector3f approach2Pos = approach2.GetTranslate();
			{
				const vector3f p0 = locTransform.GetTranslate(); // plane position
				const vector3f l = (approach2Pos - approach1Pos).Normalized(); // ray direction
				const vector3f l0 = approach1Pos + (l*10000.0f);

				if(!TPointLine::ClosestPointOnLine(p0, approach1Pos, l0, intersectionPos)) {
					Output("No point found on line segment");
				}
			}
			m_portPaths[bay].m_docking[3] = locTransform;
			m_portPaths[bay].m_docking[3].SetTranslate( intersectionPos );
			// final (docked)
			m_portPaths[bay].m_docking[4] = locTransform;
			numDockingStages = 4;

			// leaving locators ...
			matrix4x4f orient = locTransform.GetOrient(), EndOrient;
			if( exit_mts.empty() )
			{
				// leaving locators need to face in the opposite direction
				const matrix4x4f rot = matrix3x3f::Rotate(DEG2RAD(180.0f), orient.Back());
				orient = orient * rot;
				orient.SetTranslate( locTransform.GetTranslate() );
				EndOrient = approach2;
				EndOrient.SetRotationOnly(orient);
			}
			else
			{
				// leaving locators, use whatever orientation they have
				orient.SetTranslate( locTransform.GetTranslate() );
				int exitport = 0;
				for( auto &exitIt : exit_mts ) {
					PiVerify(1 == sscanf( exitIt->GetName().c_str(), "exit_port%d", &exitport ));
					if( exitport == portId )
					{
						EndOrient = exitIt->GetTransform();
						break;
					}
				}
				if( exitport == 0 )
				{
					EndOrient = approach2;
				}
			}

			// create the leaving locators
			m_portPaths[bay].m_leaving[1] = locTransform; // start - maintain the same orientation and position as when docked.
			m_portPaths[bay].m_leaving[2] = orient; // above the pad - reorient...
			m_portPaths[bay].m_leaving[2].SetTranslate( intersectionPos ); //  ...and translate to new position
			m_portPaths[bay].m_leaving[3] = EndOrient; // end (on manual after here)
			numUndockStages = 3;
		}
	}

	numDockingPorts = m_portPaths.size();

	// sanity
	assert(!m_portPaths.empty());
	assert(numDockingStages > 0);
	assert(numUndockStages > 0);

	// insanity
	for (PortPathMap::const_iterator pIt = m_portPaths.begin(), pItEnd = m_portPaths.end(); pIt!=pItEnd; ++pIt)
	{
		if (Uint32(numDockingStages-1) < pIt->second.m_docking.size()) {
			Error(
				"(%s): numDockingStages (%d) vs number of docking stages (" SIZET_FMT ")\n"
				"Must have at least the same number of entries as the number of docking stages "
				"PLUS the docking timeout at the start of the array.",
				modelName.c_str(), (numDockingStages-1), pIt->second.m_docking.size());

		} else if (Uint32(numDockingStages-1) != pIt->second.m_docking.size()) {
			Warning(
				"(%s): numDockingStages (%d) vs number of docking stages (" SIZET_FMT ")\n",
				modelName.c_str(), (numDockingStages-1), pIt->second.m_docking.size());
		}

		if (0!=pIt->second.m_leaving.size() && Uint32(numUndockStages) < pIt->second.m_leaving.size()) {
			Error(
				"(%s): numUndockStages (%d) vs number of leaving stages (" SIZET_FMT ")\n"
				"Must have at least the same number of entries as the number of leaving stages.",
				modelName.c_str(), (numDockingStages-1), pIt->second.m_docking.size());

		} else if(0!=pIt->second.m_leaving.size() && Uint32(numUndockStages) != pIt->second.m_leaving.size()) {
			Warning(
				"(%s): numUndockStages (%d) vs number of leaving stages (" SIZET_FMT ")\n",
				modelName.c_str(), numUndockStages, pIt->second.m_leaving.size());
		}

	}
}