//========================================================================== // // // //========================================================================== 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); }
/* =============== 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) ); } }
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; }
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); } }
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); }
/** * @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); }
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); } }
void SetFov(float fov) { g_fov = fov; g_fovFactor = 2 * tan(DEG2RAD(g_fov) / 2.f); }
//----------------------------------------------------------------------------- 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); } } } }
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()); } } }