Custom Prop Disc
From X-Plane SDK
Revision as of 18:45, 13 December 2012 by Sbarbour (Talk | contribs) (Code updated for 64 bit compatibility)
A discussion of customized prop discs for authors can be found here: http://wiki.x-plane.com/Custom_Prop_Discs
- Download Custom Prop Disc as project for X-Code 3.2 or newer, 32 and 64-bit Intel
- Download Custom Prop Disc as project for Microsoft Visual Studio 2010 (32 and 64-bit)
- Download Custom Prop Disc as makefile for GCC 4.x/Linux (32 and 64-bit)
/* /* prop_disc.c This sample plugin shows how to */ #include <string.h> #include <math.h> #include "XPLMDataAccess.h" #include "XPLMProcessing.h" static XPLMDataRef prop_rotation_speed_rad_sec = NULL; static XPLMDataRef prop_rotation_angle_deg = NULL; static XPLMDataRef side_angle = NULL; static XPLMDataRef prop_is_disc = NULL; static XPLMDataRef disc_s = NULL; static XPLMDataRef disc_t = NULL; static XPLMDataRef side_s = NULL; static XPLMDataRef side_t = NULL; static XPLMDataRef sim_speed = NULL; static XPLMDataRef frame_rate_period = NULL; // Interp - rescales a floating point variable, clamping to the outer limits. Handy // for mapping a range of physics behavior to something in the graphics. static float interp(float in1, float out1, float in2, float out2, float x) { if(x < in1) return out1; if(x > in2) return out2; return out1 + (out2 - out1) * (x - in1) / (in2 - in1); } // Two util funcs to write the first two slots of array datarefs...we do this a lot, // so this saves some typing. static void set_2f(XPLMDataRef r, float v1, float v2) { float v[2] = { v1, v2 }; XPLMSetDatavf(r,v,0,2); } static void set_2i(XPLMDataRef r, int i1, int i2) { int i[2] = { i1, i2 }; XPLMSetDatavi(r,i,0,2); } static float deferred_init( float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon) { // These get set once when we take over the airplane...these are custom prop disc settings that // we won't change per frame. set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/override"), 1, 1); // Our prop disc has 4 slots across and 2 down. set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/disc_s_dim"), 4, 4); set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/disc_t_dim"), 2, 2); // Alpha settings for the prop disc. set_2f(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/disc_alpha_front"), 1.0, 1.0); set_2f(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/disc_alpha_side"), 0.1, 0.1); set_2f(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/disc_alpha_inside"), 0.8, 0.8); // Side is a 2-blade prop 15 cm wide. We have 32x2 slots for side discs. set_2f(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_width") , 0.15, 0.15); set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_number_of_blades"), 2, 2); set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_s_dim"), 32, 32); set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_t_dim"), 2, 2); // Alpha setting for side disc is separate set_2f(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_alpha_front"), 0.0, 0.0); set_2f(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_alpha_side"), 1.0, 1.0); set_2f(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_alpha_inside"), 0.8, 0.8); // Do not use auto-billboarding. We will spin the side disc ourselves. set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_is_billboard"), 0, 0); return 0; } static float prop_per_frame( float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon) { float prop_speed_now[2]; float prop_angle_now[2]; float side_angle_now[2]; // First we need to know how fast the sim is really running - a function // of the sim speed and framerate period. We also need to know how fast our // disc is going. Btw s in seconds per frame. float s = XPLMGetDatai(sim_speed); s *= XPLMGetDataf(frame_rate_period); XPLMGetDatavf(prop_rotation_speed_rad_sec,prop_speed_now,0,2); // And - where is our disc right now. XPLMGetDatavf(side_angle,side_angle_now,0,2); XPLMGetDatavf(prop_rotation_angle_deg,prop_angle_now,0,2); // "Spin" the disc just a bit and write it bck. prop_angle_now[0] += prop_speed_now[0] * s * 60.0; prop_angle_now[1] += prop_speed_now[1] * s * 60.0; side_angle_now[0] += prop_speed_now[0] * s * 60.0; side_angle_now[1] += prop_speed_now[1] * s * 60.0; XPLMSetDatavf(side_angle,side_angle_now, 0, 2); XPLMSetDatavf(prop_rotation_angle_deg,prop_angle_now, 0, 2); // Individual blades or a disc? We switch at greater than 18 rads/sec spinning. set_2i(prop_is_disc, prop_speed_now[0] > 18.0, prop_speed_now[1] > 18.0); // We pick our texture slots by interping the prop speed. So as the prop speeds up, we // pick different slots. set_2f(disc_s,interp(15,0,100,2,prop_speed_now[0]),interp(15,0,100,2,prop_speed_now[1])); set_2i(disc_t,0,1); set_2f(side_s,interp(15,26,100,24,prop_speed_now[0]),interp(15,24,100,26,prop_speed_now[1])); set_2i(side_t,0,1); return -1.0; } PLUGIN_API int XPluginStart( char * outName, char * outSig, char * outDesc) { strcpy(outName, "Custom Prop Disc Example"); strcpy(outSig, "xplanesdk.examples.custom_prop_disc"); strcpy(outDesc, "A plugin that demonstrates custom prop disc patterns."); XPLMRegisterFlightLoopCallback(deferred_init, -1.0, NULL); XPLMRegisterFlightLoopCallback(prop_per_frame, -2.0, NULL); prop_rotation_speed_rad_sec = XPLMFindDataRef("sim/flightmodel2/engines/prop_rotation_speed_rad_sec"); prop_rotation_angle_deg = XPLMFindDataRef("sim/flightmodel2/engines/prop_rotation_angle_deg"); side_angle = XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_angle"); prop_is_disc = XPLMFindDataRef("sim/flightmodel2/engines/prop_is_disc"); disc_s = XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/disc_s"); disc_t = XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/disc_t"); side_s = XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_s"); side_t = XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/side_t"); sim_speed = XPLMFindDataRef("sim/time/sim_speed"); frame_rate_period = XPLMFindDataRef("sim/operation/misc/frame_rate_period"); return 1; } PLUGIN_API void XPluginStop(void) { XPLMUnregisterFlightLoopCallback(deferred_init,NULL); XPLMUnregisterFlightLoopCallback(prop_per_frame,NULL); set_2i(XPLMFindDataRef("sim/flightmodel2/engines/prop_disc/override"), 0, 0); } PLUGIN_API void XPluginDisable(void) { } PLUGIN_API int XPluginEnable(void) { return 1; } PLUGIN_API void XPluginReceiveMessage( XPLMPluginID inFromWho, int inMessage, void * inParam) { }