Search Tags
Found in pages
-
Vehicle physics lab
Sections: Downloads \ Street Legal Racing: Redline \ Modding Tools
Tags: Physics, ToolHey. I have created this tool for guys who messing around game's vehicle physic settings. It provides you interface where you can modify car wheels, suspension and pacejka in real time and see the changes immediately.
I also implemented saving and loading setup files, so you will be able to exchange them together, or just save your own creations.
Saved settings will be stored in [Game dir]\maps\Addon_Maps\Physic_Lab
How to install: Copy code below and save is as Physic_Lab_Track.java file in [Game dir]\maps\Addon_Maps\Physic_Lab\scripts\src directory. Yes, you need MWM already installed to do that.
Then just run the game and go to the Physics Lab track.
This tool is just for tests and experiments to obtain knowledge about meaning of setup parameters. It is not game editor. If you don't know what to do with it then don't use it.
The code:
package java.game; import java.io.*; import java.util.*; import java.util.resource.*; import java.game.*; import java.render.*; //Text import java.render.osd.*; //Text import java.sound.*; import java.render.osd.dialog.*; //Dialog Window import java.game.parts.*; import java.game.parts.enginepart.*; public class Physic_Lab_Track extends Track { final static String MapName = "Physics Lab"; final static String MapDescription = " Developer tool for experimenting \n with vehicle physics."; final static String MapAuthor = "Author: Miran"; final static ResourceRef MapImage = new ResourceRef(Maps.Addon_Maps.Physic_Lab:0x0DC2r); final static float TS_Version = 1.0; // Do not change it! String savePath = "maps/Addon_Maps/Physic_Lab/"; int saveFileHeader = 0x589363; int infolineCount = 16; Button[] infolines = new Button[infolineCount]; int sliderParamCount = 19; Slider[] slidersParam = new Slider[sliderParamCount]; Slider sldRadius, sldWidth, sldPatch1, sldPatch2, sldPatch3, sldFriction, sldFrictionX, sldSliction, sldStiffness, sldRollRes, sldBearing, sldMaxLoad, sldLoadSmooth, sldForce, sldDamping1, sldDamping2, sldRestLen, sldMinLen, sldMaxLen; int sliderPacejkaCount = 17; Slider[] slidersPacejka = new Slider[sliderPacejkaCount]; int grMain, grPacejka, grParams, grEmpty; static int CMD_END = 200; final static int CMD_MAIN = CMD_END++; final static int CMD_PARAMS = CMD_END++; final static int CMD_PACEJKA = CMD_END++; final static int CMD_HIDE = CMD_END++; final static int CMD_RESET_CAR = CMD_END++; final static int CMD_FLIP_CAR = CMD_END++; final static int CMD_CHANGE_CAR = CMD_END++; final static int CMD_LOAD = CMD_END++; final static int CMD_SAVE = CMD_END++; final static int CMD_APPLY_PARAMS = CMD_END++; final static int CMD_APPLY_PACEJKA = CMD_END++; final static int CMD_RADIUS_SLIDER = CMD_END++; final static int CMD_WIDTH_SLIDER = CMD_END++; final static int CMD_CP1_SLIDER = CMD_END++; final static int CMD_CP2_SLIDER = CMD_END++; final static int CMD_CP3_SLIDER = CMD_END++; final static int CMD_FRICTION_SLIDER = CMD_END++; final static int CMD_FRICTIONX_SLIDER = CMD_END++; final static int CMD_SLICTION_SLIDER = CMD_END++; final static int CMD_STIFFNESS_SLIDER = CMD_END++; final static int CMD_ROLLRES_SLIDER = CMD_END++; final static int CMD_BEARING_SLIDER = CMD_END++; final static int CMD_MAXLOAD_SLIDER = CMD_END++; final static int CMD_LOADSMOOTH_SLIDER = CMD_END++; final static int CMD_FORCE_SLIDER = CMD_END++; final static int CMD_DAMPING1_SLIDER = CMD_END++; final static int CMD_DAMPING2_SLIDER = CMD_END++; final static int CMD_MINLEN_SLIDER = CMD_END++; final static int CMD_RESTLEN_SLIDER = CMD_END++; final static int CMD_MAXLEN_SLIDER = CMD_END++; final static int CMD_PAC_SLIDER = 400; public Physic_Lab_Track() { /*posStart = new Vector3( -520.000, 0.000, 390.000 ); oriStart = new Ypr( -1.4, 0.0, 0.0 ); map = new GroundRef( Maps.Addon_Maps.Top_Gear_Track:0x0001r ); nav = new Navigator( 1.922, -1.472, 1.0, Maps.Addon_Maps.Top_Gear_Track:0x0036r, Maps.Addon_Maps.Top_Gear_Track:0x0034r, Maps.Addon_Maps.Top_Gear_Track:0x0035r, 1, 1, 0 ); //*/ posStart = new Vector3( 300.0, 1.500, -477.000 ); oriStart = new Ypr( -0.5, 0.0, 0.0 ); map = new GroundRef( maps.ROC_track:0x00000001r ); nav = new Navigator( -17.1137, -26.6, 4.9404, maps.ROC_Track.smallmap:0x00000001r, maps.ROC_Track.smallmap:0x00000002r, maps.ROC_Track.smallmap:0x00000005r, 8, 8, 8 ); //*/ GPS_Min_Zoom = 4; GPS_Max_Zoom = 8; } public void StartMap() { // Track selector run this void when you click "TAKE IT" GameLogic.changeActiveSection( new Physic_Lab_Track() ); } public void enter( GameState prev_state ) { Frontend.loadingScreen.show(); GfxEngine.flush(); super.enter( prev_state ); enableOsd( 0 ); // hide gauges and ect. Input.cursor.enable(1); osd.globalHandler = this; osd.menuKeysCreated = 1; Style btnImg = new Style( 0.06, 0.06, Frontend.smallFont, Text.ALIGN_CENTER, null ); Style btnSC = new Style( 0.22, 0.08, Frontend.smallFont, Text.ALIGN_CENTER, new ResourceRef(frontend:0x00D8r) ); Style btnMC = new Style( 0.6, 0.1, Frontend.mediumFont, Text.ALIGN_CENTER, new ResourceRef(frontend:0x00D8r) ); Style sliderStyle, sld1; Style sldk = new Style( 0.05, 0.05, Frontend.mediumFont, Text.ALIGN_RIGHT, new ResourceRef(Osd.RID_SLD_KNOB) ); Menu m; // top menu osd.createRectangle( 0.0, -0.96, 2.0, 0.08, -1, new ResourceRef(frontend:0x0028r) ); osd.createText( "PHYSICS LAB - Miran", Frontend.smallFont, Text.ALIGN_LEFT, -0.98, -0.98 ); m = osd.createMenu( btnSC, -0.5, -0.96, 0, Osd.MD_HORIZONTAL ); m.addItem( "Main", CMD_MAIN ); m.addItem( "Params", CMD_PARAMS ); m.addItem( "Pacejka", CMD_PACEJKA ); m.addItem( "Hide", CMD_HIDE ); m.addSeparator(); m.addItem( "Vehicle:", CMD_FLIP_CAR ).disable(); m.addItem( "Flip", CMD_FLIP_CAR ); m.addItem( "Reset", CMD_RESET_CAR ); m.addItem( "Change", CMD_CHANGE_CAR ); // main group grMain = osd.beginGroup(); m = osd.createMenu( btnMC, -0.8, -0.85, 0, Osd.MD_HORIZONTAL ); m.addItem( "Load settings", CMD_LOAD ); m.addItem( "Save settings", CMD_SAVE ); m = osd.createMenu( btnSC, 0.0, -0.75, 0 ); for( int i=0; i<infolineCount; i++ ) { infolines[i] = m.addItem( "", CMD_END ); infolines[i].disable(); infolines[i].label.txt.changeColor( Osd.COLOR_UNSELECTED ); } osd.hideGroup( grMain ); // params group grParams = osd.beginGroup(); sliderStyle = new Style( 0.05, 0.08, Frontend.smallFont, Text.ALIGN_LEFT, null ); m = osd.createMenu( sliderStyle, -0.7, -0.85, 0 ); sld1 = new Style( 1.7, 0.007, Frontend.mediumFont, Text.ALIGN_LEFT, new ResourceRef(frontend:0x0028r/*Osd.RID_SLD_BACK*/) ); m.setSliderStyle( sld1, sldk ); slidersParam[0] = sldRadius = m.addItem( "Radius", CMD_RADIUS_SLIDER, Math.sqrt(0.27), 0, Math.sqrt(2), 0, null ); slidersParam[1] = sldWidth = m.addItem( "Width", CMD_WIDTH_SLIDER, Math.sqrt(0.14), 0, Math.sqrt(2), 0, null ); m.addItem( "C Patch:", CMD_END ).disable(); slidersParam[2] = sldPatch1 = m.addItem( "Half Width", CMD_CP1_SLIDER, Math.sqrt(0.07), -Math.sqrt(4), Math.sqrt(4), 0, null ); slidersParam[3] = sldPatch2 = m.addItem( "Angle", CMD_CP2_SLIDER, Math.sqrt(0.2), -Math.sqrt(4), Math.sqrt(4), 0, null ); slidersParam[4] = sldPatch3 = m.addItem( " Offset", CMD_CP3_SLIDER, 0, -Math.sqrt(4), Math.sqrt(4), 0, null ); m.addSeparator(); slidersParam[5] = sldFriction = m.addItem( "Friction", CMD_FRICTION_SLIDER, Math.sqrt(2), -Math.sqrt(6), Math.sqrt(6), 0, null ); slidersParam[6] = sldFrictionX = m.addItem( "Friction X", CMD_FRICTIONX_SLIDER, Math.sqrt(1), -Math.sqrt(6), Math.sqrt(6), 0, null ); slidersParam[7] = sldSliction = m.addItem( "Sliction", CMD_SLICTION_SLIDER, Math.sqrt(1), -Math.sqrt(6), Math.sqrt(6), 0, null ); slidersParam[8] = sldStiffness = m.addItem( "Stiffness", CMD_STIFFNESS_SLIDER, Math.sqrt(50), 0, Math.sqrt(1000), 0, null ); slidersParam[9] = sldRollRes = m.addItem( "RollRes", CMD_ROLLRES_SLIDER, 0.1, 0, Math.sqrt(15), 0, null ); slidersParam[10] = sldBearing = m.addItem( "Bearing", CMD_BEARING_SLIDER, Math.sqrt(8), 0, Math.sqrt(1000), 0, null ); slidersParam[11] = sldMaxLoad = m.addItem( "MaxLoad", CMD_MAXLOAD_SLIDER, Math.sqrt(10000), Math.sqrt(0), Math.sqrt(100000), 0, null ); slidersParam[12] = sldLoadSmooth = m.addItem( "LdSmooth", CMD_LOADSMOOTH_SLIDER, Math.sqrt(0.5), -Math.sqrt(4), Math.sqrt(4), 0, null ); slidersParam[13] = sldForce = m.addItem( "Force", CMD_FORCE_SLIDER, Math.sqrt(100000), Math.sqrt(100), Math.sqrt(500000), 0, null ); m.addItem( "Damping:", CMD_END ).disable(); slidersParam[14] = sldDamping1 = m.addItem( "Bound", CMD_DAMPING1_SLIDER, Math.sqrt(2500), Math.sqrt(100), Math.sqrt(100000), 0, null ); slidersParam[15] = sldDamping2 = m.addItem( "Rebound", CMD_DAMPING2_SLIDER, Math.sqrt(2500), Math.sqrt(100), Math.sqrt(100000), 0, null ); m.addSeparator(); slidersParam[16] = sldMinLen = m.addItem( "MinLen", CMD_MINLEN_SLIDER, Math.sqrt(0.05), -Math.sqrt(1), Math.sqrt(1), 0, null ); slidersParam[17] = sldRestLen = m.addItem( "RestLen", CMD_RESTLEN_SLIDER, Math.sqrt(0.28), -Math.sqrt(1), Math.sqrt(1), 0, null ); slidersParam[18] = sldMaxLen = m.addItem( "MaxLen", CMD_MAXLEN_SLIDER, Math.sqrt(0.38), -Math.sqrt(1), Math.sqrt(1), 0, null ); m = osd.createMenu( btnMC, 0.0, 0.92, 0, Osd.MD_HORIZONTAL ); m.addItem( "Apply all params to the car", CMD_APPLY_PARAMS ); osd.hideGroup( grParams ); // pacejka group grPacejka = osd.beginGroup(); sliderStyle = new Style( 0.05, 0.1, Frontend.smallFont, Text.ALIGN_LEFT, null ); m = osd.createMenu( sliderStyle, -0.85, -0.85, 0 ); sld1 = new Style( 1.8, 0.007, Frontend.mediumFont, Text.ALIGN_LEFT, new ResourceRef(frontend:0x0028r/*Osd.RID_SLD_BACK*/) ); m.setSliderStyle( sld1, sldk ); for( int i=0; i<sliderPacejkaCount; i++ ) slidersPacejka[i] = m.addItem( "" + i, CMD_PAC_SLIDER+i, 0, -4, 4, 0, null ); // set default values setPacejkaSliderVal( 0, 0.7937006 ); // 1.0 setPacejkaSliderVal( 4, 2.79721590937 ); // 300 setPacejkaSliderVal( 8, -0.7937006 ); // -1.0 setPacejkaSliderVal( 11, 3.6880850 ); // 20000 setPacejkaSliderVal( 12, 0.7937006 ); // 1.0 setPacejkaSliderVal( 14, -0.7937006 ); // -1.0 setPacejkaSliderVal( 15, 2.3797297 ); // 80.0 setPacejkaSliderVal( 16, 0.7937006 ); // 1.0 m = osd.createMenu( btnMC, 0.0, 0.92, 0, Osd.MD_HORIZONTAL ); m.addItem( "Apply all pacejka to the car", CMD_APPLY_PACEJKA ); osd.hideGroup( grPacejka ); updateInfo(); updateSliderLabels(); } public void exit( GameState next_state ) { super.exit( next_state ); } public void updateInfo() { if( player.car && player.car.chassis ) { infolines[0].changeLabelText( player.car.chassis.vehicleName ); infolines[1].changeLabelText( "Mass: " + player.car.chassis.getMass() + "kg, 1/4: " + player.car.chassis.getMass()/4 + "kg" ); infolines[2].changeLabelText( "Force of weight: " + Config.gravity*player.car.chassis.getMass() + "N, 1/4: " + Config.gravity*player.car.chassis.getMass()/4 + "N" ); //infolines[3].changeLabelText( "More..." ); } } public void updateSliderLabels() { for( int i=0; i<sliderParamCount; i++ ) { float val = slidersParam[i].value; int sign = val > 0 ? 1 : -1; val = val*val*sign; slidersParam[i].printValue( Float.toString(val, "%1.4f") ); slidersParam[i].changeVLabelColor( Osd.COLOR_UNSELECTED ); } for( int i=0; i<sliderPacejkaCount; i++ ) { float val = slidersPacejka[i].value; if( val > 3 || val < -3 ) { float x = val > 0 ? val-2 : val+2; val = 512*x*x*x*x*x*x*x; } else if( val > 2 || val < -2 ) { float x = val > 0 ? val-1 : val+1; val = 16*x*x*x*x*x; } else val = 2*val*val*val; slidersPacejka[i].printValue( Float.toString(val, "%1.4f") ); slidersPacejka[i].changeVLabelColor( Osd.COLOR_UNSELECTED ); } } public void setPacejka( int idx ) { if( player.car && player.car.chassis ) { float val = slidersPacejka[idx].value; if( val > 3 || val < -3 ) { float x = val > 0 ? val-2 : val+2; val = 512*x*x*x*x*x*x*x; } else if( val > 2 || val < -2 ) { float x = val > 0 ? val-1 : val+1; val = 16*x*x*x*x*x; } else val = 2*val*val*val; slidersPacejka[idx].printValue( Float.toString(val, "%1.4f") ); slidersPacejka[idx].changeVLabelColor( Osd.COLOR_SELECTED ); for( int i=0; i<4; i++ ) { WheelRef w = player.car.chassis.getWheel( i ); if( w ) w.setPacejka( idx, val ); } } } public void setPacejkaSliderVal( int idx, float val ) { slidersPacejka[idx].setValue( val ); if( val > 3 || val < -3 ) { float x = val > 0 ? val-2 : val+2; val = 512*x*x*x*x*x*x*x; } else if( val > 2 || val < -2 ) { float x = val > 0 ? val-1 : val+1; val = 16*x*x*x*x*x; } else val = 2*val*val*val; slidersPacejka[idx].printValue( Float.toString(val, "%1.4f") ); } public void applyChanges() { for( int i=0; i<sliderPacejkaCount; i++ ) setPacejka( i ); } public void handleMessage( Message m ) { int handled = 0; if( m.type == Message.MT_EVENT ) { int cmd=m.cmd; if( cmd >= CMD_MAIN && cmd <= CMD_HIDE ) { osd.hideGroup( grMain ); osd.hideGroup( grPacejka ); osd.hideGroup( grParams ); osd.hideGroup( grEmpty ); if( cmd == CMD_MAIN ) { updateInfo(); osd.showGroup( grMain ); } else if( cmd == CMD_PARAMS ) osd.showGroup( grParams ); else if( cmd == CMD_PACEJKA ) osd.showGroup( grPacejka ); else if( cmd == grEmpty ) osd.showGroup( grEmpty ); handled = 1; } else if( cmd == CMD_LOAD ) { FileRequesterDialog d = new FileRequesterDialog( player.controller, Dialog.DF_FREEZE|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Load physics settings", "Load", savePath, "*.phys" ); if( d.display() == 0 ) { String filename = savePath + d.fileName; if( File.exists( filename ) ) { File file = new File( filename ); if( file.open( File.MODE_READ ) ) { if( file.readInt() == saveFileHeader ) { if( file.readInt() == sliderParamCount && file.readInt() == sliderPacejkaCount ) { for( int i=0; i<sliderParamCount; i++ ) slidersParam[i].setValue( file.readFloat() ); for( int i=0; i<sliderPacejkaCount; i++ ) slidersPacejka[i].setValue( file.readFloat() ); updateSliderLabels(); } else new WarningDialog( player.controller, Dialog.DF_HIGHPRI|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Error", "Unsupported file version!" ).display(); } else new WarningDialog( player.controller, Dialog.DF_HIGHPRI|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Error", "Corupted file!" ).display(); file.close(); } else new WarningDialog( player.controller, Dialog.DF_HIGHPRI|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Error", "Can not open the file!" ).display(); } else new WarningDialog( player.controller, Dialog.DF_HIGHPRI|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Error", "File not found!" ).display(); } } else if( cmd == CMD_SAVE ) { FileRequesterDialog d = new FileRequesterDialog( player.controller, Dialog.DF_FREEZE|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Save physics settings", "Save", savePath, "*.phys" ); if( d.display() == 0 ) { String filename = savePath + d.fileName; if( d.fileName.token( 1, "." ) != "phys" ) filename += ".phys"; int ok = 1; if( File.exists( filename ) ) { ok = 0; int res = new NoYesDialog( player.controller, Dialog.DF_HIGHPRI|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Question", "Overwrite existing file?" ).display(); if( res == 0 ) ok = 1; } if( ok ) { if( File.exists( filename ) ) File.delete( filename ); File file = new File( filename ); if( file.open( File.MODE_WRITE ) ) { file.write( saveFileHeader ); file.write( sliderParamCount ); file.write( sliderPacejkaCount ); for( int i=0; i<sliderParamCount; i++ ) file.write( slidersParam[i].value ); for( int i=0; i<sliderPacejkaCount; i++ ) file.write( slidersPacejka[i].value ); file.close(); } else new WarningDialog( player.controller, Dialog.DF_HIGHPRI|Dialog.DF_MODAL|Dialog.DF_DEFAULTBG, "Error", "Can not open the file!" ).display(); } } } else if( cmd >= CMD_RADIUS_SLIDER && cmd <= CMD_MAXLEN_SLIDER ) { int idx = cmd-CMD_RADIUS_SLIDER; float val = slidersParam[idx].value; int sign = val > 0 ? 1 : -1; val = val*val*sign; slidersParam[idx].printValue( Float.toString(val, "%1.4f") ); // update slider label slidersParam[idx].changeVLabelColor( Osd.COLOR_SELECTED ); if( player.car && player.car.chassis ) { for( int i=0; i<4; i++ ) { WheelRef w = player.car.chassis.getWheel( i ); if( w ) { if( cmd == CMD_RADIUS_SLIDER ) w.setRadius( val ); else if( cmd == CMD_WIDTH_SLIDER ) w.setWidth( val ); else if( cmd == CMD_FRICTION_SLIDER ) w.setFriction( val ); else if( cmd == CMD_FRICTIONX_SLIDER ) w.setFrictn_x( val ); else if( cmd == CMD_SLICTION_SLIDER ) w.setSliction( val ); else if( cmd == CMD_STIFFNESS_SLIDER ) w.setStiffness( val ); else if( cmd == CMD_ROLLRES_SLIDER ) w.setRollRes( val ); else if( cmd == CMD_BEARING_SLIDER ) w.setBearing( val ); else if( cmd == CMD_MAXLOAD_SLIDER ) w.setMaxLoad( val ); else if( cmd == CMD_LOADSMOOTH_SLIDER ) w.setLoadSmooth( val ); else if( cmd == CMD_FORCE_SLIDER ) w.setForce( val ); else if( cmd == CMD_MINLEN_SLIDER ) w.setMinLen( val ); else if( cmd == CMD_RESTLEN_SLIDER ) w.setRestLen( val ); else if( cmd == CMD_MAXLEN_SLIDER ) w.setMaxLen( val ); else if( cmd >= CMD_CP1_SLIDER && cmd <= CMD_CP3_SLIDER ) { sldPatch1.changeVLabelColor( Osd.COLOR_SELECTED ); sldPatch2.changeVLabelColor( Osd.COLOR_SELECTED ); sldPatch3.changeVLabelColor( Osd.COLOR_SELECTED ); float width = sldPatch1.value * sldPatch1.value * (sldPatch1.value>0 ? 1 : -1); float angle = sldPatch2.value * sldPatch2.value * (sldPatch2.value>0 ? 1 : -1); float offset = sldPatch3.value * sldPatch3.value * (sldPatch3.value>0 ? 1 : -1); w.setCPatch( width, angle, offset ); } else if( cmd >= CMD_DAMPING1_SLIDER && cmd <= CMD_DAMPING2_SLIDER ) { sldDamping1.changeVLabelColor( Osd.COLOR_SELECTED ); sldDamping2.changeVLabelColor( Osd.COLOR_SELECTED ); float bound = sldDamping1.value * sldDamping1.value * (sldDamping1.value>0 ? 1 : -1); float rebound = sldDamping2.value * sldDamping2.value * (sldDamping2.value>0 ? 1 : -1); w.setDamping( bound, rebound ); } } } player.car.wakeUp(); } } else if( cmd >= CMD_PAC_SLIDER && cmd <= CMD_PAC_SLIDER+sliderPacejkaCount ) { setPacejka( cmd-CMD_PAC_SLIDER ); handled = 1; } if( cmd == CMD_APPLY_PARAMS ) { for( int i=0; i<sliderParamCount; i++ ) slidersParam[i].sendMessage(); // emulate click handled = 1; } if( cmd == CMD_APPLY_PACEJKA ) { applyChanges(); handled = 1; } if( cmd == CMD_FLIP_CAR ) { new SfxRef( GameLogic.SFX_DRAGDROP ).play(); player.car.setMatrix( player.car.getPos(), new Ypr( player.car.getOri().y, 0, 0 ) ); } if( cmd == CMD_RESET_CAR ) { if( player.car ) { updateSliderLabels(); // reset colors new SfxRef( GameLogic.SFX_DRAGDROP ).play(); player.car.setMatrix( player.car.getPos(), new Ypr( player.car.getOri().y, 0, 0 ) ); player.car.repair(); if( player.car.chassis )player.car.chassis.updatevariables(); player.car.command( "reload" ); player.car.command( "idle"); //player.car.wakeUp(); } handled = 1; } if( cmd == CMD_CHANGE_CAR ) { updateSliderLabels(); // reset colors new SfxRef( GameLogic.SFX_DRAGDROP ).play(); int old_time = System.timeWarp(-1); System.timeWarp(0.0); // Pause Vector3 CarPos = new Vector3( posStart ); Ypr CarYpr = new Ypr( oriStart ); if ( player.car ) { CarPos = new Vector3 (player.car.getPos()); CarYpr = new Ypr (player.car.getOri()); player.render.destroy(); // Driver destroy if( nav ) nav.remMarker( mPlayer ); player.car.destroy(); player.car = null; } VehicleDescriptor nee = GameLogic.getVehicleDescriptor( VehicleType.VS_DEMO ); player.car = new Vehicle( player, nee.id, nee.colorIndex, 1+Math.random(), 1+Math.random(), 1, 1 ); player.car.setParent( map ); player.controller.command( "controllable " + player.car.id() ); player.car.setMatrix( CarPos, new Ypr(CarYpr.y, 0.0, 0.0) ); player.render = new RenderRef( map, player.driverID, "player" ); player.controller.command( "renderinstance " + player.render.id() ); player.car.setDefaultTransmission(); player.car.setDefaultSteeringHelp(); changeCamTarget(player.car); changeCamFollow(); map.command( "obs_add " + player.car.id() ); player.car.command( "reload"); player.car.command( "idle"); player.car.wakeUp(); System.timeWarp( old_time ); player.car.wakeUp(); if (nav) mPlayer = nav.addMarker( player ); updateInfo(); handled = 1; } } if( !handled ) super.handleMessage( m ); } /*public void animate() { super.animate(); if( player.car ) setMessage( player.car.getPos().toString() + " | " + player.car.getOri().toString() ); }//*/ }
-
Forza Studio
Sections: Downloads \ Other Files
Tags: .net, Application, C#, Extraction, Forza, Open Source, Tool, Utility, Visual Studios, Xbox
Features
Forza Studio 4.0 now officially supports the viewing and extraction of most cars (.carbin), wheels, brakes, rotors, calipers, tracks (.rmb.bin), and textures (.xds, .bix) from both versions of Forza 3 and Forza 4.
Controls
Its use is fairly straightforward in my opinion. Right-clicking various sections will bring up a context menu specific to that control. When viewing a model in the viewport, use the WASD keys on your keyboard to move the camera position and IJKL to look around. I’ve also included zip extraction functionality that can be found under the utilities menu for those who wish to use it instead of the usual QuickBMS script.
Requirements
.NET Framework 2.0 (or greater)
XNA Framework 3.1 (4.0 is different)