Guest User

Untitled

a guest
May 3rd, 2017
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.03 KB | None | 0 0
  1. #include "g_local.h"
  2. #include "cgame/cg_local.h"
  3. #include <vector>
  4.  
  5. // RTLED - Realtime Light Editor for rend2
  6. #define RTLCMD_NOOPTIONAL   1       // No optional arguments allowed
  7. #define RTLCMD_INRTLED      2       // Only allowed to access this command when RTLEd is enabled
  8. #define RTLCMD_SELECTED     4       // This command requires a selected light
  9.  
  10. enum realtimeLightStyle_e {
  11.     RL_POINTLIGHT,
  12.     RL_SPOTLIGHT,
  13.     RL_TUBELIGHT
  14. };
  15.  
  16. struct rtlCmd_t {
  17.     char* command;
  18.     char* usage;
  19.     char* help;
  20.     int flags;
  21.     int minimumArgs;
  22.     void (*Command)(gentity_t*);
  23. };
  24.  
  25. struct realtimeLight_t;
  26.  
  27. rtlCmd_t rtlCommands[];
  28. realtimeLight_t* selectedLight = nullptr;
  29. std::vector<realtimeLight_t> lights;
  30. qboolean rtlEdEnabled = qfalse;
  31. qboolean rtlHudEnabled = qtrue;
  32. int lastUsedLightNum = 0;
  33.  
  34. struct realtimeLight_t {
  35.     int lightNum;
  36.     realtimeLightStyle_e lightStyle;
  37.     qboolean bSelected;
  38.     qboolean bLightPreview;
  39.  
  40.     vec3_t origin;
  41.     vec3_t orientation;
  42.  
  43.     qboolean bUseTemperature;
  44.     vec3_t color;
  45.     float temperature;
  46.  
  47.     float attenuation;
  48.     float intensity;
  49.     float radius;
  50.     float length;
  51.  
  52.     realtimeLight_t() {
  53.         realtimeLight_t(lastUsedLightNum++, g_entities[0].currentOrigin);
  54.     }
  55.  
  56.     realtimeLight_t(int _lightNum, vec3_t _origin) {
  57.         lightNum = _lightNum;
  58.         bSelected = qtrue;
  59.         selectedLight->bSelected = qfalse;
  60.         selectedLight = this;
  61.         VectorCopy(_origin, origin);
  62.         VectorClear(orientation);
  63.  
  64.         bUseTemperature = qfalse;
  65.         temperature = 1000.0f;
  66.         bLightPreview = qtrue;
  67.         lightStyle = RL_POINTLIGHT;
  68.  
  69.         attenuation = 128.0f;
  70.         intensity = 300.0f;
  71.         radius = 128.0f;
  72.         length = 50.0f;
  73.  
  74.         gi.Printf("Created new light: %i\n", lightNum);
  75.         gi.Printf("Selected light: %i\n", lightNum);
  76.     }
  77.  
  78.     realtimeLight_t(realtimeLight_t& other) {
  79.         realtimeLight_t(lastUsedLightNum++, other.origin);
  80.  
  81.         gi.Printf("Copying light %i\n", other.lightNum);
  82.  
  83.         VectorCopy(other.orientation, orientation);
  84.  
  85.         bUseTemperature = other.bUseTemperature;
  86.         temperature = other.temperature;
  87.         bLightPreview = other.bLightPreview;
  88.         lightStyle = other.lightStyle;
  89.  
  90.         attenuation = other.attenuation;
  91.         intensity = other.intensity;
  92.         radius = other.radius;
  93.         length = other.length;
  94.     }
  95.  
  96.     ~realtimeLight_t() {
  97.         gi.Printf("Deleted light: %i\n", lightNum);
  98.         if (bSelected) {
  99.             selectedLight = nullptr;
  100.         }
  101.     }
  102. };
  103.  
  104. void Rtl_f(gentity_t* ent) {
  105.     rtlEdEnabled = (qboolean)!rtlEdEnabled;
  106.  
  107.     if (rtlEdEnabled) {
  108.         gi.Printf("Realtime Lighting Editor enabled\n");
  109.     }
  110.     else {
  111.         gi.Printf("Realtime Lighting Editor disabled\n");
  112.     }
  113. }
  114.  
  115. void Rtl_Help_f(gentity_t* ent) {
  116.  
  117. }
  118.  
  119. void Rtl_Hud_f(gentity_t* ent) {
  120.     rtlHudEnabled = (qboolean)!rtlHudEnabled;
  121.     if (rtlHudEnabled) {
  122.         gi.Printf("Realtime Lighting Editor HUD enabled\n");
  123.     }
  124.     else {
  125.         gi.Printf("Realtime Lighting Editor HUD disabled\n");
  126.     }
  127. }
  128.  
  129. void Rtl_List_f(gentity_t* ent) {
  130.     int i = 0;
  131.  
  132.     gi.Printf("List of Realtime Lighting editor commands:\n\n");
  133.  
  134.     while (rtlCommands[i].Command) {
  135.         gi.Printf("\t ^%i%s^%i - ^%i%s\n", COLOR_YELLOW, rtlCommands[i].command, COLOR_WHITE, COLOR_CYAN, rtlCommands[i].usage);
  136.         i++;
  137.     }
  138. }
  139.  
  140. void Rtl_Select_f(gentity_t* ent) {
  141.     int lightNum = atoi(gi.argv(1));
  142.     if (lightNum < 0 || lightNum >= lights.size()) {
  143.         gi.Printf("Invalid light number, must be between 0 and %d\n", lastUsedLightNum);
  144.     }
  145.     for (auto it = lights.begin(); it != lights.end(); ++it) {
  146.         if (it->lightNum == lightNum) {
  147.             selectedLight = &(*it);
  148.             gi.Printf("Selected light %d\n", lightNum);
  149.             return;
  150.         }
  151.     }
  152.     gi.Printf("Couldn't find light %d\n", lightNum);
  153. }
  154.  
  155. void Rtl_Info_f(gentity_t* ent) {
  156.     gi.Printf("LIGHT %d ", selectedLight->lightNum);
  157.     switch (selectedLight->lightStyle) {
  158.         case RL_POINTLIGHT:
  159.             gi.Printf("(POINT)\n");
  160.             break;
  161.         case RL_SPOTLIGHT:
  162.             gi.Printf("(SPOT)\n");
  163.             break;
  164.         case RL_TUBELIGHT:
  165.             gi.Printf("(TUBE)\n");
  166.             break;
  167.     }
  168.     gi.Printf("Origin: %.2f %.2f %.2f\n", selectedLight->origin[0], selectedLight->origin[1], selectedLight->origin[2]);
  169.     gi.Printf("Orientation: %.2f %.2f %.2f\n", selectedLight->orientation[0], selectedLight->orientation[1], selectedLight->orientation[2]);
  170.     if (selectedLight->bLightPreview) {
  171.         gi.Printf("IN PREVIEW\n");
  172.     }
  173.     if (selectedLight->bUseTemperature) {
  174.         gi.Printf("Temperature: %.2f\n", selectedLight->temperature);
  175.     }
  176.     else {
  177.         gi.Printf("RGB Color: %.2f %.2f %.2f\n", selectedLight->color[0], selectedLight->color[1], selectedLight->color[2]);
  178.     }
  179.  
  180.     gi.Printf("Radius: %.2f\n", selectedLight->radius);
  181.     gi.Printf("Intensity: %.2f\n", selectedLight->intensity);
  182.     gi.Printf("Attenuation: %.2f\n", selectedLight->attenuation);
  183.     gi.Printf("Length: %.2f\n", selectedLight->length);
  184. }
  185.  
  186. void Rtl_New_f(gentity_t* ent) {
  187.     realtimeLight_t light;
  188.     lights.push_back(light);
  189. }
  190.  
  191. void Rtl_Delete_f(gentity_t* ent) {
  192.     if (gi.argc() > 1) {
  193.         int num = atoi(gi.argv(1));
  194.         for (auto it = lights.begin(); it != lights.end(); ++it) {
  195.             if (it->lightNum == num) {
  196.                 it = lights.erase(it);
  197.                 return;
  198.             }
  199.         }
  200.         gi.Printf("Could not find light number %i\n");
  201.     }
  202.     else if (selectedLight != nullptr) {
  203.         for (auto it = lights.begin(); it != lights.end(); ++it) {
  204.             if (it->lightNum == selectedLight->lightNum) {
  205.                 it = lights.erase(it);
  206.                 return;
  207.             }
  208.         }
  209.     }
  210.     else {
  211.         gi.Printf("Usage: rtl_delete [index]\n");
  212.     }
  213. }
  214.  
  215. void Rtl_DeleteAll_f(gentity_t* ent) {
  216.     size_t len = lights.size();
  217.  
  218.     selectedLight = nullptr;
  219.     lights.clear();
  220.  
  221.     gi.Printf("Deleted %d lights\n", len);
  222. }
  223.  
  224. void Rtl_Save_f(gentity_t* ent) {
  225.  
  226. }
  227.  
  228. void Rtl_Load_f(gentity_t* ent) {
  229.  
  230. }
  231.  
  232. void Rtl_Style_f(gentity_t* ent) {
  233.     char* style = gi.argv(1);
  234.    
  235.     if (!Q_stricmp(style, "point")) {
  236.         selectedLight->lightStyle = RL_POINTLIGHT;
  237.     }
  238.     else if (!Q_stricmp(style, "tube")) {
  239.         selectedLight->lightStyle = RL_TUBELIGHT;
  240.     }
  241.     else if (!Q_stricmp(style, "spot")) {
  242.         selectedLight->lightStyle = RL_SPOTLIGHT;
  243.     }
  244. }
  245.  
  246. void Rtl_Color_f(gentity_t* ent) {
  247.     float r = atof(gi.argv(1));
  248.     float g = atof(gi.argv(2));
  249.     float b = atof(gi.argv(3));
  250.     vec3_t color = { r, g, b };
  251.  
  252.     if (selectedLight->bUseTemperature) {
  253.         gi.Printf("This light uses temperature settings instead of RGB color. \n\
  254.                    Use the temperature command first to enable RGB color.\n");
  255.         return;
  256.     }
  257.  
  258.     VectorCopy(color, selectedLight->color);
  259. }
  260.  
  261. void Rtl_Temperature_f(gentity_t* ent) {
  262.     int usetemp = atoi(gi.argv(1));
  263.     if (usetemp) {
  264.         selectedLight->bUseTemperature = qtrue;
  265.     }
  266.     else {
  267.         selectedLight->bUseTemperature = qfalse;
  268.     }
  269.  
  270.     if (gi.argc() > 2) {
  271.         float temp = atof(gi.argv(2));
  272.         selectedLight->temperature = temp;
  273.     }
  274. }
  275.  
  276. void Rtl_Attenuation_f(gentity_t* ent) {
  277.     float atten = atof(gi.argv(1));
  278.  
  279.     selectedLight->attenuation = atten;
  280. }
  281.  
  282. void Rtl_Intensity_f(gentity_t* ent) {
  283.     float intensity = atof(gi.argv(1));
  284.     selectedLight->intensity = intensity;
  285. }
  286.  
  287. void Rtl_Radius_f(gentity_t* ent) {
  288.     float radius = atof(gi.argv(1));
  289.     selectedLight->radius = radius;
  290. }
  291.  
  292. void Rtl_Length_f(gentity_t* ent) {
  293.     float length = atof(gi.argv(1));
  294.     selectedLight->length = length;
  295. }
  296.  
  297. void Rtl_Orientation_f(gentity_t* ent) {
  298.     float pitch = atof(gi.argv(1));
  299.     float yaw = atof(gi.argv(2));
  300.     float roll = atof(gi.argv(3));
  301.     vec3_t angles = { pitch, yaw, roll };
  302.     VectorCopy(selectedLight->orientation, angles);
  303. }
  304.  
  305. void Rtl_Origin_f(gentity_t* ent) {
  306.     VectorCopy(ent->currentOrigin, selectedLight->origin);
  307.    
  308.     gi.Printf("Light moved to %.2f %.2f %.2f\n", selectedLight->origin[0], selectedLight->origin[1], selectedLight->origin[2]);
  309. }
  310.  
  311. void Rtl_Nudge_f(gentity_t* ent) {
  312.     float nudgeX = atof(gi.argv(1));
  313.     float nudgeY = atof(gi.argv(2));
  314.     float nudgeZ = atof(gi.argv(3));
  315.  
  316.     selectedLight->origin[0] += nudgeX;
  317.     selectedLight->origin[1] += nudgeY;
  318.     selectedLight->origin[2] += nudgeZ;
  319.  
  320.     gi.Printf("Light moved to %.2f %.2f %.2f\n", selectedLight->origin[0], selectedLight->origin[1], selectedLight->origin[2]);
  321. }
  322.  
  323. void Rtl_Preview_f(gentity_t* ent) {
  324.     selectedLight->bLightPreview = (qboolean)!selectedLight->bLightPreview;
  325.     if (selectedLight->bLightPreview) {
  326.         gi.Printf("Preview mode enabled\n");
  327.     }
  328.     else {
  329.         gi.Printf("Preview mode disabled\n");
  330.     }
  331. }
  332.  
  333. rtlCmd_t rtlCommands[] = {
  334.     {
  335.         "rtl",
  336.         "rtl",
  337.         "Toggles the rend2 Realtime Light Editor (\"SLIGHTED\")",
  338.         RTLCMD_NOOPTIONAL,
  339.         0,
  340.         Rtl_f
  341.     },
  342.     {
  343.         "rtl_help",
  344.         "rtl_help [command name]",
  345.         "Lists all of the commands, or probes a specific command for help.",
  346.         0,
  347.         0,
  348.         Rtl_Help_f
  349.     },
  350.     {
  351.         "rtl_hud",
  352.         "rtl_hud",
  353.         "Toggles the SLIGHTED heads up display",
  354.         RTLCMD_NOOPTIONAL | RTLCMD_INRTLED,
  355.         0,
  356.         Rtl_Hud_f
  357.     },
  358.     {
  359.         "rtl_list",
  360.         "rtl_list",
  361.         "Lists all of the static lights on the map.",
  362.         RTLCMD_INRTLED | RTLCMD_NOOPTIONAL,
  363.         0,
  364.         Rtl_List_f
  365.     },
  366.     {
  367.         "rtl_select",
  368.         "rtl_select <index>",
  369.         "Selects a specific light index.",
  370.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL,
  371.         1,
  372.         Rtl_Select_f
  373.     },
  374.     {
  375.         "rtl_info",
  376.         "rtl_info [index]",
  377.         "Retrieves all possible info about either a specific light index or the currently selected light.",
  378.         RTLCMD_INRTLED,
  379.         0,
  380.         Rtl_Info_f
  381.     },
  382.     {
  383.         "rtl_new",
  384.         "rtl_new",
  385.         "Creates a new light",
  386.         RTLCMD_INRTLED | RTLCMD_NOOPTIONAL,
  387.         0,
  388.         Rtl_New_f
  389.     },
  390.     {
  391.         "rtl_delete",
  392.         "rtl_delete [index]",
  393.         "Deletes either the currently selected light, or a specific index.",
  394.         RTLCMD_INRTLED,
  395.         0,
  396.         Rtl_Delete_f
  397.     },
  398.     {
  399.         "rtl_deleteall",
  400.         "rtl_deleteall",
  401.         "Deletes all static lights on the level",
  402.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL,
  403.         0,
  404.         Rtl_DeleteAll_f
  405.     },
  406.     {
  407.         "rtl_save",
  408.         "rtl_save [filename]",
  409.         "Saves all of the static lights. The name of the map is the default file name.",
  410.         RTLCMD_INRTLED,
  411.         0,
  412.         Rtl_Save_f
  413.     },
  414.     {
  415.         "rtl_load",
  416.         "rtl_load [filename]",
  417.         "Purges all of the existing static lights and loads a new file. The default is the name of the map.",
  418.         RTLCMD_INRTLED,
  419.         0,
  420.         Rtl_Load_f
  421.     },
  422.     {
  423.         "rtl_style",
  424.         "rtl_style <style>",
  425.         "Tells the renderer how this light should be rendered. 'Style' can be one of the following: \n\
  426.          'point' for pointlights \n\
  427.          'tube' for tubelights \n\
  428.          'spot' for spotlights \n",
  429.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  430.         1,
  431.         Rtl_Style_f
  432.     },
  433.     {
  434.         "rtl_color",
  435.         "rtl_color <R> <G> <B>",
  436.         "Adjusts the color of the currently selected light. The color values should be between 0 and 1.0. \n\
  437.          This command doesn't do anything if temperature-based lighting is enabled for this light.",
  438.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  439.         3,
  440.         Rtl_Color_f
  441.     },
  442.     {
  443.         "rtl_temperature",
  444.         "rtl_temperature <0/1> [Temperature]",
  445.         "Use temperature-based lighting instead of RGB? (true/false) \n\
  446.          The second parameter uses the Kelvin scale (default temperature is 1000 degrees).",
  447.         RTLCMD_INRTLED|RTLCMD_SELECTED,
  448.         1,
  449.         Rtl_Temperature_f
  450.     },
  451.     {
  452.         "rtl_attenuation",
  453.         "rtl_attenuation <radius>",
  454.         "Adjusts the attenuation radius of the light, or how far the light reaches.",
  455.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  456.         1,
  457.         Rtl_Attenuation_f
  458.     },
  459.     {
  460.         "rtl_intensity",
  461.         "rtl_intensity <intensity>",
  462.         "Adjusts how intense the light is, or how brightly it appears.",
  463.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  464.         1,
  465.         Rtl_Intensity_f
  466.     },
  467.     {
  468.         "rtl_radius",
  469.         "rtl_radius <radius>",
  470.         "Adjusts the radius of the light, or how large the emitting light source should be.",
  471.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  472.         1,
  473.         Rtl_Radius_f
  474.     },
  475.     {
  476.         "rtl_length",
  477.         "rtl_length <length>",
  478.         "For tubelights only - adjusts how long the emitting light source should be.",
  479.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  480.         1,
  481.         Rtl_Length_f
  482.     },
  483.     {
  484.         "rtl_orientation",
  485.         "rtl_orientation <pitch> <yaw> <roll>",
  486.         "For spotlights and tubelights only - adjusts the angle that the light is facing.",
  487.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  488.         3,
  489.         Rtl_Orientation_f
  490.     },
  491.     {
  492.         "rtl_origin",
  493.         "rtl_origin",
  494.         "Moves the light to your current player origin.",
  495.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  496.         0,
  497.         Rtl_Origin_f
  498.     },
  499.     {
  500.         "rtl_nudge",
  501.         "rtl_nudge <X> <Y> <Z>",
  502.         "Moves the light a certain number of units in a particular direction.",
  503.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  504.         3,
  505.         Rtl_Nudge_f
  506.     },
  507.     {
  508.         "rtl_preview",
  509.         "rtl_preview",
  510.         "Toggles previewing of this light. \n\
  511.          Note that if a light already has static lights on it, this will lead to an incorrect preview. \n\
  512.          Only pointlights can be previewed.",
  513.         RTLCMD_INRTLED|RTLCMD_NOOPTIONAL|RTLCMD_SELECTED,
  514.         0,
  515.         Rtl_Preview_f
  516.     },
  517.     {
  518.         nullptr,
  519.         nullptr,
  520.         nullptr,
  521.         0, 0,
  522.         nullptr
  523.     }
  524. };
  525.  
  526. qboolean Rend2Enabled() {
  527.     return qtrue; // TODO: need a better method of determining this.
  528. }
  529.  
  530. qboolean Rtl_Command_f(gentity_t* ent) {
  531.     int i = 0;
  532.     int argc = gi.argc();
  533.     char* cmd = gi.argv(0);
  534.  
  535.     if (!Rend2Enabled()) {
  536.         return qfalse;
  537.     }
  538.  
  539.     while (rtlCommands[i].command) {
  540.         if (!Q_stricmp(rtlCommands[i].command, cmd)) {
  541.             if (argc - 1 < rtlCommands[i].minimumArgs) {
  542. usage:
  543.                 gi.Printf("usage: %s\n", rtlCommands[i].usage);
  544.             }
  545.             else if (argc - 1 != rtlCommands[i].minimumArgs && rtlCommands[i].flags & RTLCMD_NOOPTIONAL) {
  546.                 goto usage;
  547.             }
  548.             else if (rtlCommands[i].flags & RTLCMD_INRTLED && !rtlEdEnabled) {
  549.                 gi.Printf("The Realtime Lighting Editor must be enabled to use this command.\n\
  550.                            (Hint: try enabling it with \"rtl\")\n");
  551.             }
  552.             else if (rtlCommands[i].flags & RTLCMD_SELECTED && selectedLight == nullptr) {
  553.                 gi.Printf("You need to select a light in order to use this command.\n\
  554.                            (Hint: you can select a light using \"rtl_select\".)\n");
  555.             }
  556.             else {
  557.                 rtlCommands[i].Command(ent);
  558.             }
  559.             return qtrue;
  560.         }
  561.         i++;
  562.     }
  563.  
  564.     return qfalse;
  565. }
  566.  
  567. // Initialization / shutdown code, which occurs at the start and end of the game, or upon level load.
  568. // This is responsible for loading the realtime lighting file which rend2 uses.
  569. void Rtl_Initialize() {
  570.     if (!Rend2Enabled()) {
  571.         return;
  572.     }
  573.  
  574.     // When we load the .rtl file, we keep the array of lights alive so that we can open them up in the editor if we want to.
  575. }
  576.  
  577. void Rtl_Shutdown() {
  578.     // Just remove the light list
  579.     lights.clear();
  580.     selectedLight = nullptr;
  581. }
Advertisement
Add Comment
Please, Sign In to add comment