mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-27 22:07:20 +01:00
Merge pull request #448 from mastercheese-dev/plasma-charge
Draw the plasma pistol's charge with the picture, and keep the meter's values.
This commit is contained in:
5 files changed
+299
-109
No files matched your search
@@ -117,6 +117,7 @@ symbols in this file:
|
||||
#include "models/models.h"
|
||||
#include "networking/network_connection.h"
|
||||
#include "objects/objects.h"
|
||||
#include "rasterizer/rasterizer.h" /* port: rasterizer_memory_alloc */
|
||||
#include "rasterizer/rasterizer_model_types.h"
|
||||
#include "render/render.h"
|
||||
#include "saved games/game_state.h"
|
||||
@@ -509,7 +510,21 @@ void first_person_weapon_draw(
|
||||
struct animation_graph *animation_graph= animation_graph_definition_get(
|
||||
weapon_definition->weapon.interface_definition.first_person_animations.index);
|
||||
struct render_lighting *lighting= object_get_cached_render_lighting(unit_index, FLT_MAX);
|
||||
real values[NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS];
|
||||
real const *weapon_functions = weapon->object.outgoing_function_values;
|
||||
real const *unit_functions = unit->object.outgoing_function_values;
|
||||
real *kept;
|
||||
|
||||
/* port: the tick's functions, moved into this frame, so the
|
||||
charge clicks with the picture instead of once a tick; kept
|
||||
in the rasterizer's memory for the frame, as the groups drawn
|
||||
later read them (render_objects.c) */
|
||||
object_function_values_for_render(first_person_weapon->weapon_index, values);
|
||||
if ((kept = rasterizer_memory_alloc(values, sizeof(values))) != NULL)
|
||||
weapon_functions = kept;
|
||||
object_function_values_for_render(unit_index, values);
|
||||
if ((kept = rasterizer_memory_alloc(values, sizeof(values))) != NULL)
|
||||
unit_functions = kept;
|
||||
model_effect.modifier_shader= NULL;
|
||||
if (TEST_FLAG(unit->unit.flags, _unit_active_camouflaged_bit) ||
|
||||
unit->unit.active_camouflage>0.0f)
|
||||
@@ -540,7 +555,7 @@ void first_person_weapon_draw(
|
||||
model_node_matrices,
|
||||
NULL,
|
||||
weapon->object.outgoing_change_colors,
|
||||
weapon->object.outgoing_function_values,
|
||||
weapon_functions,
|
||||
lighting,
|
||||
&render.camera.position,
|
||||
0.0f,
|
||||
@@ -569,7 +584,7 @@ void first_person_weapon_draw(
|
||||
model_effect.modifier_animation.colors= shield_color_colors(unit_index,
|
||||
unit->object.outgoing_change_colors);
|
||||
model_effect.modifier_animation.values= overshield_effect_values(unit_index,
|
||||
unit->object.outgoing_function_values, TRUE);
|
||||
unit_functions, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -589,7 +604,7 @@ void first_person_weapon_draw(
|
||||
model_node_matrices,
|
||||
NULL,
|
||||
unit->object.outgoing_change_colors,
|
||||
unit->object.outgoing_function_values,
|
||||
unit_functions,
|
||||
lighting,
|
||||
&render.camera.position,
|
||||
0.0f,
|
||||
|
||||
+248
-102
@@ -97,6 +97,19 @@ index, which reads no function: 0 */
|
||||
|
||||
#define OBJECT_FRAME_INDEX_GET(object_index) ((object_index) + game_time_get())
|
||||
|
||||
/* port: set while a frame is drawn, so a function read for the picture is
|
||||
the tick's value moved into the frame */
|
||||
static int object_function_render_depth = 0;
|
||||
|
||||
static real object_function_addition(
|
||||
struct object_datum *object,
|
||||
struct object_function_definition *function,
|
||||
real huh,
|
||||
real const *outgoing,
|
||||
boolean *active);
|
||||
static real object_function_wrap(
|
||||
real value);
|
||||
|
||||
/* ---------- structures */
|
||||
|
||||
struct object_globals
|
||||
@@ -1550,6 +1563,77 @@ void object_permute_region(
|
||||
return;
|
||||
}
|
||||
|
||||
void object_functions_set_for_render(
|
||||
boolean for_render)
|
||||
{
|
||||
if (for_render)
|
||||
object_function_render_depth++;
|
||||
else if (object_function_render_depth > 0)
|
||||
object_function_render_depth--;
|
||||
}
|
||||
|
||||
void object_function_values_for_render(
|
||||
long object_index,
|
||||
real values[NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS])
|
||||
{
|
||||
struct object_datum *object = object_get(object_index);
|
||||
struct object_definition *definition = object_definition_get(object->definition_index);
|
||||
/* port: where the picture is, between the previous tick (0) and this one
|
||||
(1) (render_interpolation.c); 1 outside an interpolated frame (Smooth
|
||||
Motion off), where the tick's own values are shown */
|
||||
real fraction = render_interpolation_fraction();
|
||||
short function_count = (short)MIN(
|
||||
definition->object.functions.count,
|
||||
NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS);
|
||||
short function_index;
|
||||
real huh;
|
||||
real back;
|
||||
|
||||
csmemcpy(
|
||||
values,
|
||||
object->object.outgoing_function_values,
|
||||
sizeof(object->object.outgoing_function_values));
|
||||
if (!(fraction >= 0.0f) || !(fraction < 1.0f))
|
||||
return;
|
||||
|
||||
back = 1.0f - fraction;
|
||||
huh = (57 * DATUM_INDEX_TO_ABSOLUTE_INDEX(object_index) + game_time_get()) * 0.033333335f;
|
||||
for (function_index = 0; function_index < function_count; function_index++)
|
||||
{
|
||||
struct object_function_definition *function = TAG_BLOCK_GET_ELEMENT(
|
||||
&definition->object.functions,
|
||||
function_index,
|
||||
struct object_function_definition);
|
||||
boolean active;
|
||||
real output;
|
||||
|
||||
/* port: an additive function steps by a whole tick: the picture
|
||||
is that part of the step back from this tick's value. Anything else
|
||||
is the function at the picture's moment. */
|
||||
if (TEST_FLAG(function->flags, _object_function_clip_to_bounds_and_normalize))
|
||||
{
|
||||
output = object_function_addition(
|
||||
object,
|
||||
function,
|
||||
huh,
|
||||
object->object.outgoing_function_values,
|
||||
&active);
|
||||
values[function_index] = object_function_wrap(
|
||||
object->object.outgoing_function_values[function_index] - back * output);
|
||||
}
|
||||
else
|
||||
{
|
||||
output = object_function_addition(
|
||||
object,
|
||||
function,
|
||||
huh - back * 0.033333335f,
|
||||
values,
|
||||
&active);
|
||||
values[function_index] = output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean object_get_function_value(
|
||||
long object_index,
|
||||
short function_index,
|
||||
@@ -1573,7 +1657,17 @@ boolean object_get_function_value(
|
||||
it reads as off */
|
||||
if (VALID_INDEX(function_index, NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS))
|
||||
{
|
||||
*value_reference = object->object.outgoing_function_values[function_index];
|
||||
if (object_function_render_depth > 0)
|
||||
{
|
||||
real shown[NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS];
|
||||
|
||||
object_function_values_for_render(object_index, shown);
|
||||
*value_reference = shown[function_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
*value_reference = object->object.outgoing_function_values[function_index];
|
||||
}
|
||||
|
||||
result = TEST_FLAG(object->object.functions_active_flags, function_index);
|
||||
}
|
||||
@@ -5175,6 +5269,150 @@ static void object_delete_recursive(
|
||||
return;
|
||||
}
|
||||
|
||||
static real object_function_input_value(
|
||||
struct object_datum *object,
|
||||
real const *outgoing,
|
||||
short index)
|
||||
{
|
||||
if ((unsigned long)(index - 1) >=
|
||||
(unsigned long)(NUMBER_OF_INCOMING_OBJECT_FUNCTIONS + NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS))
|
||||
return 0.0f;
|
||||
if (index >= NUMBER_OF_INCOMING_OBJECT_FUNCTIONS + 1)
|
||||
return outgoing[index - NUMBER_OF_INCOMING_OBJECT_FUNCTIONS - 1];
|
||||
return object->object.incoming_function_values[index - 1];
|
||||
}
|
||||
|
||||
static real object_function_wrap(
|
||||
real value)
|
||||
{
|
||||
value -= (real)floor((double)value);
|
||||
if (!(value >= 0.0f))
|
||||
value += 1.0f;
|
||||
return value;
|
||||
}
|
||||
|
||||
/* port: the original's loop body, as one function, so that the picture's
|
||||
values (object_function_values_for_render) are found as the tick's are: what
|
||||
one tick stores, before an additive function folds it into the value it
|
||||
already held. `outgoing` is the functions already computed. */
|
||||
static real object_function_addition(
|
||||
struct object_datum *object,
|
||||
struct object_function_definition *function,
|
||||
real huh,
|
||||
real const *outgoing,
|
||||
boolean *active)
|
||||
{
|
||||
real value;
|
||||
real output;
|
||||
boolean function_is_active = TRUE;
|
||||
real period = function->runtime_one_over_period;
|
||||
|
||||
if (function->scale_period_by_function_index)
|
||||
{
|
||||
real function_value = object_function_input_value(
|
||||
object,
|
||||
outgoing,
|
||||
function->scale_period_by_function_index);
|
||||
|
||||
if (function_value > 0.f)
|
||||
period = period / function_value;
|
||||
}
|
||||
|
||||
value = periodic_function_evaluate(function->function_type, huh * period);
|
||||
|
||||
if (function->scale_function_by_function_index)
|
||||
{
|
||||
value *= object_function_input_value(
|
||||
object,
|
||||
outgoing,
|
||||
function->scale_function_by_function_index);
|
||||
}
|
||||
|
||||
if (TEST_FLAG(function->flags, _object_function_invert_function_bit))
|
||||
value = 1.f - value;
|
||||
|
||||
if (function->wobble_magnitude != 0.f)
|
||||
{
|
||||
real val = periodic_function_evaluate(
|
||||
function->wobble_function_type,
|
||||
huh * function->wobble_period);
|
||||
|
||||
value += (2.f * function->wobble_magnitude * (val - 0.5f));
|
||||
}
|
||||
|
||||
if (function->square_wave_threshold != 0.f)
|
||||
value = value > function->square_wave_threshold ? 1.f : 0.f;
|
||||
|
||||
if (function->step_count > 1)
|
||||
{
|
||||
real floor_value = floor(function->step_count * value);
|
||||
|
||||
value = floor_value * function->runtime_reciprocal_step_count;
|
||||
}
|
||||
|
||||
if (function->runtime_reciprocal_sawtooth_count > 0.f)
|
||||
value = fmod(value, function->runtime_reciprocal_sawtooth_count);
|
||||
|
||||
if (function->add_function_index)
|
||||
{
|
||||
value += object_function_input_value(object, outgoing, function->add_function_index);
|
||||
value = MIN(value, 1.f);
|
||||
}
|
||||
|
||||
if (function->scale_result_by_function_index)
|
||||
{
|
||||
value *= object_function_input_value(
|
||||
object,
|
||||
outgoing,
|
||||
function->scale_result_by_function_index);
|
||||
}
|
||||
|
||||
output = transition_function_evaluate(function->map_result_to_transition_function, value);
|
||||
|
||||
if (function->scale_by > 0.f)
|
||||
output *= function->scale_by;
|
||||
|
||||
if (function->bounds_mode == _object_function_scale_to_fit_bounds)
|
||||
{
|
||||
output *= (function->upper_bound - function->lower_bound);
|
||||
output += function->lower_bound;
|
||||
|
||||
if (function->lower_bound + _real_epsilon >= output)
|
||||
{
|
||||
function_is_active = TEST_FLAG(
|
||||
function->flags,
|
||||
_object_function_does_not_deactivate_below_lower_bound_bit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function->lower_bound + _real_epsilon >= output)
|
||||
{
|
||||
output = function->lower_bound;
|
||||
function_is_active = TEST_FLAG(
|
||||
function->flags,
|
||||
_object_function_does_not_deactivate_below_lower_bound_bit);
|
||||
}
|
||||
|
||||
if (output > function->upper_bound)
|
||||
output = function->upper_bound;
|
||||
|
||||
if (function->bounds_mode == _object_function_clip_to_bounds_and_normalize)
|
||||
{
|
||||
output = (output - function->lower_bound) * function->runtime_reciprocal_bounds_range;
|
||||
}
|
||||
}
|
||||
|
||||
if (function->turn_off_with_function_index != NONE &&
|
||||
!TEST_FLAG(object->object.functions_active_flags, function->turn_off_with_function_index))
|
||||
{
|
||||
function_is_active = FALSE;
|
||||
}
|
||||
|
||||
*active = function_is_active;
|
||||
return output;
|
||||
}
|
||||
|
||||
static void object_compute_function_values(
|
||||
long object_index)
|
||||
{
|
||||
@@ -5194,112 +5432,20 @@ static void object_compute_function_values(
|
||||
|
||||
for (function_index = 0; function_index<function_count; ++function_index)
|
||||
{
|
||||
real value;
|
||||
real output;
|
||||
|
||||
struct object_function_definition* function = TAG_BLOCK_GET_ELEMENT(
|
||||
&object_definition->object.functions,
|
||||
function_index,
|
||||
struct object_function_definition);
|
||||
boolean function_is_active = TRUE;
|
||||
real period = function->runtime_one_over_period;
|
||||
|
||||
if (function->scale_period_by_function_index)
|
||||
{
|
||||
real function_value = OBJECT_INCOMING_FUNCTION_GET_VALUE(object, function->scale_period_by_function_index);
|
||||
if (function_value>0.f)
|
||||
{
|
||||
period = period/function_value;
|
||||
}
|
||||
}
|
||||
|
||||
value = periodic_function_evaluate(function->function_type, huh*period);
|
||||
|
||||
if (function->scale_function_by_function_index)
|
||||
{
|
||||
value*= OBJECT_INCOMING_FUNCTION_GET_VALUE(object, function->scale_function_by_function_index);
|
||||
}
|
||||
|
||||
if (TEST_FLAG(function->flags, _object_function_invert_function_bit))
|
||||
{
|
||||
value = 1.f-value;
|
||||
}
|
||||
|
||||
if (function->wobble_magnitude!=0.f)
|
||||
{
|
||||
real val = periodic_function_evaluate(function->wobble_function_type, huh*function->wobble_period);
|
||||
value+= (2.f*function->wobble_magnitude * (val-0.5f));
|
||||
}
|
||||
|
||||
if (function->square_wave_threshold!=0.f)
|
||||
{
|
||||
value = value>function->square_wave_threshold ? 1.f : 0.f ;
|
||||
}
|
||||
|
||||
if (function->step_count>1)
|
||||
{
|
||||
real floor_value = floor(function->step_count*value);
|
||||
value = floor_value*function->runtime_reciprocal_step_count;
|
||||
}
|
||||
|
||||
if (function->runtime_reciprocal_sawtooth_count>0.f)
|
||||
{
|
||||
value = fmod(value, function->runtime_reciprocal_sawtooth_count);
|
||||
}
|
||||
|
||||
if (function->add_function_index)
|
||||
{
|
||||
value+= OBJECT_INCOMING_FUNCTION_GET_VALUE(object, function->add_function_index);
|
||||
value = MIN(value, 1.f);
|
||||
}
|
||||
|
||||
if (function->scale_result_by_function_index)
|
||||
{
|
||||
value*= OBJECT_INCOMING_FUNCTION_GET_VALUE(object, function->scale_result_by_function_index);
|
||||
}
|
||||
|
||||
output = transition_function_evaluate(function->map_result_to_transition_function, value);
|
||||
|
||||
if (function->scale_by>0.f)
|
||||
{
|
||||
output*= function->scale_by;
|
||||
}
|
||||
|
||||
if (function->bounds_mode==_object_function_scale_to_fit_bounds)
|
||||
{
|
||||
output*= (function->upper_bound-function->lower_bound);
|
||||
output+= function->lower_bound;
|
||||
|
||||
if (function->lower_bound+_real_epsilon>=output)
|
||||
{
|
||||
function_is_active = TEST_FLAG(function->flags, _object_function_does_not_deactivate_below_lower_bound_bit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function->lower_bound+_real_epsilon>=output)
|
||||
{
|
||||
output = function->lower_bound;
|
||||
function_is_active = TEST_FLAG(function->flags, _object_function_does_not_deactivate_below_lower_bound_bit);
|
||||
}
|
||||
|
||||
if (output>function->upper_bound)
|
||||
{
|
||||
output = function->upper_bound;
|
||||
}
|
||||
|
||||
if (function->bounds_mode==_object_function_clip_to_bounds_and_normalize)
|
||||
{
|
||||
output = (output-function->lower_bound)*function->runtime_reciprocal_bounds_range;
|
||||
}
|
||||
}
|
||||
|
||||
if (function->turn_off_with_function_index!=NONE &&
|
||||
!TEST_FLAG(object->object.functions_active_flags, function->turn_off_with_function_index))
|
||||
{
|
||||
function_is_active = FALSE;
|
||||
}
|
||||
boolean function_is_active;
|
||||
real output = object_function_addition(
|
||||
object,
|
||||
function,
|
||||
huh,
|
||||
object->object.outgoing_function_values,
|
||||
&function_is_active);
|
||||
|
||||
/* bit 1 is the additive function (the bounds-mode name shares its
|
||||
value). It folds this tick onto the value already held. */
|
||||
if (TEST_FLAG(function->flags, _object_function_clip_to_bounds_and_normalize))
|
||||
{
|
||||
output = fmod(output+object->object.outgoing_function_values[function_index], 1.f);
|
||||
|
||||
@@ -430,6 +430,11 @@ void object_start_interpolation(long object_index, short frame_count);
|
||||
void object_offset_interpolation(long object_index, real_vector3d *offset);
|
||||
void object_permute_region(long object_index, char *permutation_name, short desired_region_index, boolean active_flag);
|
||||
boolean object_get_function_value(long object_index, short function_index, real *value_reference);
|
||||
/* port: the picture is drawn between ticks. While this is set, a function
|
||||
read for drawing is the tick's value moved forward by the fraction of the
|
||||
tick that has passed. */
|
||||
void object_functions_set_for_render(boolean for_render);
|
||||
void object_function_values_for_render(long object_index, real values[NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS]);
|
||||
short objects_in_clusters_by_indices(unsigned long class_flags, short cluster_count, short const *cluster_indices, short maximum_object_count, long *object_indices);
|
||||
long object_index_from_name_index(short name_index);
|
||||
/* port: this object takes a scenario name nobody holds, the way a placed
|
||||
|
||||
@@ -325,6 +325,7 @@ static void render_window(
|
||||
render.local_player_index = local_player_index;
|
||||
render.camera = *camera;
|
||||
render.frustum = *frustum;
|
||||
object_functions_set_for_render(TRUE);
|
||||
parameters.camera = *rasterizer_camera;
|
||||
parameters.frustum = *rasterizer_frustum;
|
||||
parameters.rasterizer_target = rasterizer_target;
|
||||
@@ -444,6 +445,7 @@ static void render_window(
|
||||
rasterizer_debug_draw();
|
||||
rasterizer_window_end();
|
||||
profile_render_window_end();
|
||||
object_functions_set_for_render(FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -486,6 +486,13 @@ static void render_object_list(
|
||||
real_matrix4x3 const *node_matrices = legs ?
|
||||
first_person_legs_node_matrices(object_index, object_get_node_matrices(object_index)) :
|
||||
object_get_node_matrices(object_index);
|
||||
/* port: the function values the picture shows
|
||||
(object_function_values_for_render), kept in the rasterizer's memory
|
||||
for the frame: a modifier's group, a queued transparent part and a
|
||||
child that copies this modifier read them after this block is done,
|
||||
and the overshield finds its own values by their address
|
||||
(overshield_effect.c), so they are not copied again */
|
||||
real const *shown_functions = object->object.outgoing_function_values;
|
||||
|
||||
if (!object_is_first_person_camera(object_index) || render.camera.mirrored || (legs && node_matrices))
|
||||
{
|
||||
@@ -529,6 +536,17 @@ static void render_object_list(
|
||||
|
||||
if (!data->shadow)
|
||||
{
|
||||
/* port: the tick's functions, moved into this frame, so a
|
||||
charge clicks with the picture instead of once a tick */
|
||||
{
|
||||
real values[NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS];
|
||||
real *kept;
|
||||
|
||||
object_function_values_for_render(object_index, values);
|
||||
kept = rasterizer_memory_alloc(values, sizeof(values));
|
||||
if (kept)
|
||||
shown_functions = kept;
|
||||
}
|
||||
if (definition->object.modifier_shader.index != NONE)
|
||||
{
|
||||
model_effect.modifier_shader = shader_definition_get(
|
||||
@@ -546,8 +564,8 @@ static void render_object_list(
|
||||
(port/linux/game/overshield_effect.c) */
|
||||
model_effect.modifier_animation.values =
|
||||
TEST_FLAG(_object_mask_unit, object->object.type) ?
|
||||
overshield_effect_values(object_index, object->object.outgoing_function_values, FALSE) :
|
||||
object->object.outgoing_function_values;
|
||||
overshield_effect_values(object_index, shown_functions, FALSE) :
|
||||
shown_functions;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -629,7 +647,7 @@ static void render_object_list(
|
||||
node_matrices,
|
||||
object->object.region_permutations,
|
||||
object->object.outgoing_change_colors,
|
||||
object->object.outgoing_function_values,
|
||||
shown_functions,
|
||||
data->lighting,
|
||||
&object->object.bounding_sphere_center,
|
||||
object->object.bounding_sphere_radius,
|
||||
@@ -665,9 +683,13 @@ static void render_object_list(
|
||||
if (!data->shadow && !legs && object->object.first_widget_index != NONE)
|
||||
{
|
||||
struct render_animation animation;
|
||||
real widget_functions[NUMBER_OF_OUTGOING_OBJECT_FUNCTIONS];
|
||||
|
||||
/* port: the tick's functions, moved into this frame (the
|
||||
widgets read them as they are drawn, here) */
|
||||
object_function_values_for_render(object_index, widget_functions);
|
||||
animation.colors = object->object.outgoing_change_colors;
|
||||
animation.values = object->object.outgoing_function_values;
|
||||
animation.values = widget_functions;
|
||||
widgets_render(object_index, data->lighting, &animation);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user