mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-19 01:00:27 +02:00
371 lines
8.9 KiB
C
371 lines
8.9 KiB
C
/*
|
|
PHYSICS.C
|
|
|
|
symbols in this file:
|
|
0013FF60 0080:
|
|
_pin_fraction (0000)
|
|
0013FFE0 00b0:
|
|
_physics_get_features_in_sphere (0000)
|
|
00140090 0070:
|
|
_code_00140090 (0000)
|
|
00140100 0110:
|
|
_render_debug_physics (0000)
|
|
00140210 0100:
|
|
_physics_instance_new (0000)
|
|
00140310 00a0:
|
|
_physics_test_point (0000)
|
|
001403B0 0120:
|
|
_physics_test_vector (0000)
|
|
001404D0 0150:
|
|
_code_001404d0 (0000)
|
|
00140620 0100:
|
|
_code_00140620 (0000)
|
|
00140720 0b80:
|
|
_physics_compute_new (0000)
|
|
001412A0 0470:
|
|
_code_001412a0 (0000)
|
|
00141710 0490:
|
|
_code_00141710 (0000)
|
|
00141BA0 0180:
|
|
_code_00141ba0 (0000)
|
|
00141D20 01b0:
|
|
_code_00141d20 (0000)
|
|
00141ED0 07c0:
|
|
_physics_update_new (0000)
|
|
00142690 1430:
|
|
_code_00142690 (0000)
|
|
00143AC0 0260:
|
|
_physics_update (0000)
|
|
0028BC20 008d:
|
|
??_C@_0IN@ODNFDOFI@mass_point?9?$DOground_material_type@ (0000)
|
|
0028BCB0 0021:
|
|
??_C@_0CB@OHGIJBLL@c?3?2halo?2SOURCE?2physics?2physics?4c@ (0000)
|
|
0028BCD4 0004:
|
|
__real@45ea6000 (0000)
|
|
0028BCD8 0057:
|
|
??_C@_0FH@DDOACPI@unit_definition?9?$DOunit?4blip_type?$DO@ (0000)
|
|
0028BD30 0015:
|
|
??_C@_0BF@GMDJIBPD@model_instance_valid?$AA@ (0000)
|
|
0028BD48 0010:
|
|
??_C@_0BA@LNKGLGKJ@rotated_forward?$AA@ (0000)
|
|
0028BD58 000b:
|
|
??_C@_0L@GBBDLPMF@rotated_up?$AA@ (0000)
|
|
0028BD64 000f:
|
|
??_C@_0P@OGJNHPDG@up?$CB?$DNrotated_up?$AA@ (0000)
|
|
0028BD74 0019:
|
|
??_C@_0BJ@GEGCJHGH@forward?$CB?$DNrotated_forward?$AA@ (0000)
|
|
0028BD90 0004:
|
|
__real@364c6ce0 (0000)
|
|
0028BD94 0004:
|
|
__real@34a5b36e (0000)
|
|
0028BD98 0004:
|
|
__real@3b33abb1 (0000)
|
|
0028BDA0 0008:
|
|
__real@3f80000000000000 (0000)
|
|
0028BDA8 0012:
|
|
??_C@_0BC@MDPNAJDL@?$CGangular_velocity?$AA@ (0000)
|
|
0028BDBC 0016:
|
|
??_C@_0BG@NPNNHCFI@?$CGangular_acceleration?$AA@ (0000)
|
|
0028BDD4 0011:
|
|
??_C@_0BB@IHCLBKLO@?$CGlinear_velocity?$AA@ (0000)
|
|
0028BDE8 0015:
|
|
??_C@_0BF@LNOJMOGI@?$CGlinear_acceleration?$AA@ (0000)
|
|
0028BE00 001d:
|
|
??_C@_0BN@FOPAIIBD@instance?9?$DOphysics?9?$DOmass?$DO0?40f?$AA@ (0000)
|
|
0028BE20 0018:
|
|
??_C@_0BI@HOJEHDKE@?$CGobject?9?$DOobject?4forward?$AA@ (0000)
|
|
0028BE38 0013:
|
|
??_C@_0BD@JHPMDDBM@?$CGobject?9?$DOobject?4up?$AA@ (0000)
|
|
0028BE4C 001c:
|
|
??_C@_0BM@EKBNDJOG@?$CGtranslational_acceleration?$AA@ (0000)
|
|
0028BE68 000d:
|
|
??_C@_0N@EMPCNLII@magic_torque?$AA@ (0000)
|
|
0028BE78 000c:
|
|
??_C@_0M@LNGNIFCJ@magic_force?$AA@ (0000)
|
|
0030CEB4 002c:
|
|
_global_gravity (0000)
|
|
_global_water_density (0004)
|
|
_global_air_density (0008)
|
|
_global_physics_collision_depth (000c)
|
|
_depths_of_hell (0010)
|
|
0045E01A 0001:
|
|
_debug_physics_disable_penetration_freeze (0000)
|
|
*/
|
|
|
|
/* ---------- headers */
|
|
|
|
#include "cseries.h"
|
|
#include "physics.h"
|
|
|
|
#include "collision_features.h"
|
|
#include "objects/object_definitions.h"
|
|
#include "objects/objects.h"
|
|
#include "physics_definitions.h"
|
|
#include "render/render_debug.h"
|
|
|
|
/* ---------- constants */
|
|
|
|
/* ---------- macros */
|
|
|
|
/* ---------- structures */
|
|
|
|
/* ---------- prototypes */
|
|
|
|
/* ---------- globals */
|
|
|
|
real global_gravity = 0.0035651792f;
|
|
real global_water_density = 1.0f;
|
|
real global_air_density = 0.0011f;
|
|
real global_physics_collision_depth = 0.2f;
|
|
real_plane3d depths_of_hell =
|
|
{
|
|
{ 0.0f, 0.0f, 1.0f },
|
|
-256.0f
|
|
};
|
|
|
|
/* ---------- public code */
|
|
|
|
real pin_fraction(
|
|
real value,
|
|
real begin,
|
|
real end)
|
|
{
|
|
if (begin < end)
|
|
{
|
|
if (value <= begin)
|
|
return 0.0f;
|
|
else if (value >= end)
|
|
return 1.0f;
|
|
else
|
|
return (value - begin) / (end - begin);
|
|
}
|
|
else
|
|
{
|
|
if (value <= end)
|
|
return 1.0f;
|
|
else if (value >= begin)
|
|
return 0.0f;
|
|
else
|
|
return (begin - value) / (begin - end);
|
|
}
|
|
}
|
|
|
|
boolean physics_get_features_in_sphere(
|
|
struct physics_instance const *instance,
|
|
real_point3d const *center,
|
|
real radius,
|
|
real height,
|
|
real width,
|
|
struct collision_feature_list *features)
|
|
{
|
|
short mass_point_index;
|
|
real scaled_radius;
|
|
|
|
for (mass_point_index = 0;
|
|
mass_point_index < instance->physics->mass_points.count;
|
|
mass_point_index++)
|
|
{
|
|
struct mass_point_definition const *mass_point = TAG_BLOCK_GET_ELEMENT(
|
|
&instance->physics->mass_points,
|
|
mass_point_index,
|
|
struct mass_point_definition);
|
|
real_point3d point;
|
|
|
|
matrix4x3_transform_point(&instance->world_matrix, &mass_point->position, &point);
|
|
|
|
scaled_radius = mass_point->radius * instance->world_matrix.scale;
|
|
|
|
collision_features_from_point(
|
|
&point,
|
|
height,
|
|
scaled_radius + width,
|
|
instance->object_index,
|
|
NONE,
|
|
0,
|
|
NONE,
|
|
NONE,
|
|
features);
|
|
}
|
|
|
|
return features->count[_collision_feature_sphere] ||
|
|
features->count[_collision_feature_cylinder] ||
|
|
features->count[_collision_feature_prism];
|
|
}
|
|
|
|
void render_debug_physics(
|
|
struct physics_instance *instance)
|
|
{
|
|
struct object_datum *object = object_get(instance->object_index);
|
|
struct object_definition *definition = object_definition_get(object->definition_index);
|
|
real_point3d center_of_mass;
|
|
short mass_point_index;
|
|
|
|
matrix4x3_transform_point(
|
|
&instance->world_matrix,
|
|
&instance->physics->center_of_mass,
|
|
¢er_of_mass);
|
|
|
|
render_debug_vectors(
|
|
TRUE,
|
|
¢er_of_mass,
|
|
&instance->world_matrix.forward,
|
|
&instance->world_matrix.up,
|
|
definition->object.bounding_radius);
|
|
|
|
for (mass_point_index = 0;
|
|
mass_point_index < instance->physics->mass_points.count;
|
|
mass_point_index++)
|
|
{
|
|
struct mass_point_definition const *mass_point = TAG_BLOCK_GET_ELEMENT(
|
|
&instance->physics->mass_points,
|
|
mass_point_index,
|
|
struct mass_point_definition);
|
|
real_point3d position;
|
|
real_vector3d forward;
|
|
real_vector3d up;
|
|
|
|
matrix4x3_transform_point(
|
|
&instance->world_matrix,
|
|
&mass_point->position,
|
|
&position);
|
|
matrix4x3_transform_normal(
|
|
&instance->world_matrix,
|
|
&mass_point->forward,
|
|
&forward);
|
|
matrix4x3_transform_normal(
|
|
&instance->world_matrix,
|
|
&mass_point->up,
|
|
&up);
|
|
|
|
render_debug_sphere(
|
|
TRUE,
|
|
&position,
|
|
mass_point->radius,
|
|
global_real_argb_white);
|
|
render_debug_vectors(
|
|
TRUE,
|
|
&position,
|
|
&forward,
|
|
&up,
|
|
mass_point->radius * 0.5f);
|
|
}
|
|
}
|
|
|
|
boolean physics_instance_new(
|
|
struct physics_instance *instance,
|
|
long object_index)
|
|
{
|
|
struct object_datum *object = object_get(object_index);
|
|
struct object_definition *definition = object_definition_get(object->definition_index);
|
|
real_point3d center_of_mass;
|
|
|
|
if (definition->object.physics.index != NONE)
|
|
{
|
|
instance->object_index = object_index;
|
|
instance->physics = physics_definition_get(definition->object.physics.index);
|
|
|
|
instance->world_matrix.scale = 1.0f;
|
|
object_get_origin(object_index, &instance->world_matrix.position);
|
|
object_get_orientation(object_index, &instance->world_matrix.forward, &instance->world_matrix.up);
|
|
cross_product3d(&instance->world_matrix.up, &instance->world_matrix.forward, &instance->world_matrix.left);
|
|
|
|
set_real_point3d(¢er_of_mass,
|
|
-instance->physics->center_of_mass.x,
|
|
-instance->physics->center_of_mass.y,
|
|
-instance->physics->center_of_mass.z);
|
|
matrix4x3_transform_point(&instance->world_matrix, ¢er_of_mass, ¢er_of_mass);
|
|
instance->world_matrix.position = center_of_mass;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
boolean physics_test_point(
|
|
struct physics_instance const *instance,
|
|
real_point3d const *point)
|
|
{
|
|
real_point3d local_point;
|
|
struct physics_definition const *physics;
|
|
short mass_point_index;
|
|
|
|
matrix4x3_inverse_transform_point(&instance->world_matrix, point, &local_point);
|
|
physics = instance->physics;
|
|
|
|
for (mass_point_index = 0;
|
|
mass_point_index < physics->mass_points.count;
|
|
mass_point_index++)
|
|
{
|
|
struct mass_point_definition const *mass_point = TAG_BLOCK_GET_ELEMENT(
|
|
&physics->mass_points,
|
|
mass_point_index,
|
|
struct mass_point_definition);
|
|
|
|
if (point_in_sphere(&local_point, &mass_point->position, mass_point->radius))
|
|
return TRUE;
|
|
|
|
physics = instance->physics;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
boolean physics_test_vector(
|
|
struct physics_instance const *instance,
|
|
real_point3d const *point,
|
|
real_vector3d const *vector,
|
|
struct physics_test_vector_result *result)
|
|
{
|
|
boolean hit = FALSE;
|
|
real_point3d local_point;
|
|
real_vector3d local_vector;
|
|
real_vector3d normal;
|
|
short mass_point_index;
|
|
|
|
result->t = REAL_MAX;
|
|
|
|
matrix4x3_inverse_transform_point(&instance->world_matrix, point, &local_point);
|
|
matrix4x3_inverse_transform_vector(&instance->world_matrix, vector, &local_vector);
|
|
|
|
for (mass_point_index = 0;
|
|
mass_point_index < instance->physics->mass_points.count;
|
|
mass_point_index++)
|
|
{
|
|
struct mass_point_definition const *mass_point = TAG_BLOCK_GET_ELEMENT(
|
|
&instance->physics->mass_points,
|
|
mass_point_index,
|
|
struct mass_point_definition);
|
|
real t;
|
|
|
|
if (sphere_test_vector3d(
|
|
&mass_point->position,
|
|
mass_point->radius,
|
|
&local_point,
|
|
&local_vector,
|
|
&t,
|
|
&normal) &&
|
|
result->t > t)
|
|
{
|
|
real_point3d intersection;
|
|
|
|
result->t = t;
|
|
// Preserve the January inline schedule without emitting a point_from_line3d COMDAT.
|
|
intersection.x = local_vector.i*t + local_point.x;
|
|
intersection.y = local_vector.j*t + local_point.y;
|
|
intersection.z = local_vector.k*t + local_point.z;
|
|
plane3d_from_point_and_normal(
|
|
&result->plane,
|
|
&intersection,
|
|
&normal);
|
|
hit = TRUE;
|
|
}
|
|
}
|
|
|
|
if (hit)
|
|
matrix4x3_transform_plane(&instance->world_matrix, &result->plane, &result->plane);
|
|
|
|
return hit;
|
|
}
|
|
/* ---------- private code */
|