Compare commits
13 Commits
659c25dbe5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 21b22653b5 | |||
| 0736eb77b2 | |||
| 17c3469602 | |||
| 8e2bc651b9 | |||
| dc18060729 | |||
| 0d35175aed | |||
| 98058856a6 | |||
| ada1acb402 | |||
| be4775ff93 | |||
| f62203973f | |||
| 9c2f32f5a3 | |||
| e0f1dd5e70 | |||
| 0d51dc8236 |
@@ -41,6 +41,8 @@ Renderable :: struct {
|
||||
visible: bool = true;
|
||||
type : Renderable_Type; @DontSerialize
|
||||
|
||||
use_default_pipeline: bool = true;
|
||||
|
||||
model: Model_Handle; @DontSerialize
|
||||
nodes: [MAX_NODES] Node_Render_Data; @DontSerialize
|
||||
num_nodes: s64; @DontSerialize
|
||||
@@ -55,6 +57,9 @@ MAX_CHILDREN :: 16;
|
||||
SPHERE;
|
||||
BOX;
|
||||
CAPSULE;
|
||||
TRIANGLE_MESH;
|
||||
CONVEX_MESH;
|
||||
CHARACTER;
|
||||
}
|
||||
|
||||
Physics_Lock :: enum_flags u8 {
|
||||
@@ -76,6 +81,7 @@ MAX_CHILDREN :: 16;
|
||||
dynamic_friction: float;
|
||||
restitution: float;
|
||||
|
||||
render_collider: bool;
|
||||
collider_color: Color;
|
||||
|
||||
lock: Physics_Lock;
|
||||
@@ -93,6 +99,10 @@ MAX_CHILDREN :: 16;
|
||||
radius: float;
|
||||
half_height: float;
|
||||
}
|
||||
character : struct {
|
||||
radius: float;
|
||||
height: float;
|
||||
}
|
||||
}
|
||||
|
||||
physx_handle: PhysX_Handle;
|
||||
|
||||
@@ -42,13 +42,6 @@ Vector3i :: struct {
|
||||
z: int;
|
||||
}
|
||||
|
||||
Color :: #type,isa Vector4;
|
||||
|
||||
Colored_Vert :: struct {
|
||||
position: Vector2;
|
||||
color : Color;
|
||||
}
|
||||
|
||||
AABB :: struct {
|
||||
min: Vector3 = .{FLOAT32_INFINITY, FLOAT32_INFINITY, FLOAT32_INFINITY};
|
||||
max: Vector3 = .{-FLOAT32_INFINITY, -FLOAT32_INFINITY, -FLOAT32_INFINITY};
|
||||
@@ -423,6 +416,60 @@ ease_in_out_sine :: (x: float) -> float {
|
||||
return -(cos(PI * x) - 1.0) * 0.5;
|
||||
}
|
||||
|
||||
// Color
|
||||
Color :: #type,isa Vector4;
|
||||
|
||||
Colored_Vert :: struct {
|
||||
position: Vector2;
|
||||
color : Color;
|
||||
}
|
||||
|
||||
linear_to_srgb :: (c: float) -> float {
|
||||
if (c <= 0.0031308)
|
||||
return 12.92 * c;
|
||||
else
|
||||
return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
|
||||
}
|
||||
|
||||
linear_to_srgb :: (c: Vector3) -> Vector3 {
|
||||
return Vector3.{
|
||||
linear_to_srgb(c.x),
|
||||
linear_to_srgb(c.y),
|
||||
linear_to_srgb(c.z)
|
||||
};
|
||||
}
|
||||
|
||||
linear_to_srgb :: (c: $T) -> T {
|
||||
srgb_color := c;
|
||||
srgb_color.x = linear_to_srgb(c.x);
|
||||
srgb_color.y = linear_to_srgb(c.y);
|
||||
srgb_color.z = linear_to_srgb(c.z);
|
||||
return srgb_color;
|
||||
}
|
||||
|
||||
srgb_to_linear :: (c: float) -> float {
|
||||
if c <= 0.04045
|
||||
return c / 12.92;
|
||||
else
|
||||
return pow((c + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
srgb_to_linear :: (c: Vector3) -> Vector3 {
|
||||
return float3(
|
||||
srgbToLinear(c.r),
|
||||
srgbToLinear(c.g),
|
||||
srgbToLinear(c.b)
|
||||
);
|
||||
}
|
||||
|
||||
srgb_to_linear :: (c: $T) -> T {
|
||||
linear_color := c;
|
||||
linear_color.x = srgb_to_linear(c.x);
|
||||
linear_color.y = srgb_to_linear(c.y);
|
||||
linear_color.z = srgb_to_linear(c.z);
|
||||
return linear_color;
|
||||
}
|
||||
|
||||
#import "PCG";
|
||||
#import "Math";
|
||||
#load "frustum.jai";
|
||||
|
||||
@@ -9,9 +9,11 @@ Mesh_Entity :: struct {
|
||||
init_entity :: (e: *Mesh_Entity) {
|
||||
if e.model_path.count > 0 {
|
||||
load_model_into_entity(e, get_or_load_model(e.model_path));
|
||||
#if PHYSICS {
|
||||
e.flags |= .PHYSICS;
|
||||
e.physics.type = .BOX;
|
||||
e.physics.box.half_extent = .{0.5,0.5,0.5};
|
||||
e.physics.type = .TRIANGLE_MESH;
|
||||
}
|
||||
//e.physics.box.half_extent = .{0.5,0.5,0.5};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,9 @@ unload_scene :: (scene: *Scene) {
|
||||
destroy_entity(e);
|
||||
}
|
||||
|
||||
#if PHYSICS {
|
||||
deinit_physx_scene(scene);
|
||||
}
|
||||
|
||||
free(scene.name);
|
||||
fini(*scene.pool);
|
||||
@@ -163,7 +165,7 @@ reload_scene :: (scene: *Scene) {
|
||||
load_scene(name);
|
||||
}
|
||||
|
||||
create_scene :: (name: string = "", max_entities: s64 = 256) -> *Scene {
|
||||
create_scene :: (name: string = "", max_entities: s64 = 256, trigger_callbacks := false) -> *Scene {
|
||||
scene := New(Scene);
|
||||
new_name := name;
|
||||
|
||||
@@ -195,7 +197,9 @@ create_scene :: (name: string = "", max_entities: s64 = 256) -> *Scene {
|
||||
|
||||
array_reserve(*scene.entities, max_entities);
|
||||
|
||||
#if PHYSICS {
|
||||
init_physx_scene(scene);
|
||||
}
|
||||
|
||||
scene.directional_light.color_and_intensity = .{1,1,1,2};
|
||||
scene.directional_light.direction = to_v4(normalize(Vector3.{0.4, -0.7, 0.4}));
|
||||
@@ -205,6 +209,12 @@ create_scene :: (name: string = "", max_entities: s64 = 256) -> *Scene {
|
||||
dir_light_data.direction = scene.directional_light.direction;
|
||||
upload_data_to_buffer(engine.renderer, engine.directional_light_buffer, *dir_light_data, size_of(Directional_Light_Buffer_Data));
|
||||
|
||||
if trigger_callbacks {
|
||||
if engine.procs.on_scene_loaded != null {
|
||||
engine.procs.on_scene_loaded(scene, engine.mode);
|
||||
}
|
||||
}
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ Editor :: struct {
|
||||
camera: Camera;
|
||||
transform_gizmo: Transform_Gizmo;
|
||||
selected_entities: [..] *Entity;
|
||||
selected_entity_transforms : Table(*Entity, Transform);
|
||||
|
||||
mouse_viewport_state: Interaction_State;
|
||||
last_right_mouse_click_time: float;
|
||||
@@ -171,10 +172,12 @@ init_transform_gizmo :: () {
|
||||
}
|
||||
|
||||
update_transform_gizmo :: (ray: Ray, mouse_position: Vector2) -> bool {
|
||||
if engine.editor.selected_entities.count != 1 return false;
|
||||
|
||||
selected_entity := engine.editor.selected_entities[0];
|
||||
|
||||
if engine.editor.selected_entities.count != 1 {
|
||||
// Hardcode to world + translation when selecting multiple entities
|
||||
// We currently don't need to do anything but translate in world space, when having multiple entities selected
|
||||
engine.editor.transform_gizmo.space = .WORLD;
|
||||
engine.editor.transform_gizmo.transform_type = .TRANSLATION;
|
||||
} else {
|
||||
if key_down(.TAB) {
|
||||
if engine.editor.transform_gizmo.space == {
|
||||
case .WORLD;
|
||||
@@ -183,6 +186,16 @@ update_transform_gizmo :: (ray: Ray, mouse_position: Vector2) -> bool {
|
||||
engine.editor.transform_gizmo.space = .WORLD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
position : Vector3;
|
||||
for e: engine.editor.selected_entities {
|
||||
position += e.transform.position;
|
||||
}
|
||||
|
||||
position /= cast(float)engine.editor.selected_entities.count;
|
||||
|
||||
selected_entity := engine.editor.selected_entities[0];
|
||||
|
||||
if engine.editor.transform_gizmo.space == {
|
||||
case .WORLD;
|
||||
@@ -191,17 +204,28 @@ update_transform_gizmo :: (ray: Ray, mouse_position: Vector2) -> bool {
|
||||
set_rotation(*engine.editor.transform_gizmo.transform, selected_entity.transform.orientation);
|
||||
}
|
||||
|
||||
engine.editor.transform_gizmo.actual_entity_position = position;
|
||||
|
||||
if engine.editor.transform_gizmo.transform_type == {
|
||||
case .TRANSLATION;
|
||||
if !key_pressed(.MOUSE_LEFT) {
|
||||
if key_pressed(.CTRL) {
|
||||
engine.editor.transform_gizmo.selected_axis = .NONE;
|
||||
table_reset(*engine.editor.selected_entity_transforms);
|
||||
} else {
|
||||
selected_axis, t := intersect_translation_gizmo(ray);
|
||||
engine.editor.transform_gizmo.selected_axis = selected_axis;
|
||||
table_reset(*engine.editor.selected_entity_transforms);
|
||||
}
|
||||
} else if engine.editor.transform_gizmo.can_use && engine.editor.transform_gizmo.selected_axis != .NONE {
|
||||
first_update := key_down(.MOUSE_LEFT);
|
||||
|
||||
if first_update {
|
||||
engine.editor.transform_gizmo.actual_entity_position = selected_entity.transform.position;
|
||||
push_transform_undo(engine.editor.selected_entities[0]);
|
||||
|
||||
for engine.editor.selected_entities {
|
||||
push_transform_undo(it);
|
||||
table_add(*engine.editor.selected_entity_transforms, it, it.transform);
|
||||
}
|
||||
}
|
||||
|
||||
// Move the currently selected entity along the selected axis
|
||||
@@ -231,7 +255,7 @@ update_transform_gizmo :: (ray: Ray, mouse_position: Vector2) -> bool {
|
||||
}
|
||||
|
||||
r1 : Ray;
|
||||
r1.origin = selected_entity.transform.position;
|
||||
r1.origin = position;
|
||||
r1.direction = axis_vec;
|
||||
|
||||
r2 := normalized_screen_to_ray(*engine.editor.camera, mouse_position);
|
||||
@@ -246,21 +270,28 @@ update_transform_gizmo :: (ray: Ray, mouse_position: Vector2) -> bool {
|
||||
|
||||
position_change := new_position - engine.editor.transform_gizmo.first_hit_position;
|
||||
|
||||
entity_position := engine.editor.transform_gizmo.actual_entity_position + position_change;
|
||||
for e: engine.editor.selected_entities {
|
||||
found, transform := table_find_new(*engine.editor.selected_entity_transforms, e);
|
||||
assert(found);
|
||||
|
||||
entity_position := transform.position + position_change;
|
||||
if engine.editor.transform_gizmo.snap_to_grid {
|
||||
snap_interval := Vector3.{1,1,1};
|
||||
entity_position.x -= fmod_cycling(entity_position.x - selected_entity.snap_offset.x, snap_interval.x);// + selected_entity.snap_offset.x;
|
||||
entity_position.y -= fmod_cycling(entity_position.y - selected_entity.snap_offset.y, snap_interval.y);// + selected_entity.snap_offset.y;
|
||||
entity_position.z -= fmod_cycling(entity_position.z - selected_entity.snap_offset.z, snap_interval.z);// + selected_entity.snap_offset.z;
|
||||
entity_position.x -= fmod_cycling(entity_position.x - e.snap_offset.x, snap_interval.x);// + selected_entity.snap_offset.x;
|
||||
entity_position.y -= fmod_cycling(entity_position.y - e.snap_offset.y, snap_interval.y);// + selected_entity.snap_offset.y;
|
||||
entity_position.z -= fmod_cycling(entity_position.z - e.snap_offset.z, snap_interval.z);// + selected_entity.snap_offset.z;
|
||||
} else if selected_entity.flags & Entity_Flags.SNAP_TO_GRID {
|
||||
entity_position.x -= fmod_cycling(entity_position.x - selected_entity.snap_offset.x, selected_entity.snap_intervals.x);// + selected_entity.snap_offset.x;
|
||||
entity_position.y -= fmod_cycling(entity_position.y - selected_entity.snap_offset.y, selected_entity.snap_intervals.y);// + selected_entity.snap_offset.y;
|
||||
entity_position.z -= fmod_cycling(entity_position.z - selected_entity.snap_offset.z, selected_entity.snap_intervals.z);// + selected_entity.snap_offset.z;
|
||||
entity_position.x -= fmod_cycling(entity_position.x - e.snap_offset.x, e.snap_intervals.x);// + selected_entity.snap_offset.x;
|
||||
entity_position.y -= fmod_cycling(entity_position.y - e.snap_offset.y, e.snap_intervals.y);// + selected_entity.snap_offset.y;
|
||||
entity_position.z -= fmod_cycling(entity_position.z - e.snap_offset.z, e.snap_intervals.z);// + selected_entity.snap_offset.z;
|
||||
}
|
||||
|
||||
selected_entity.transform.position = entity_position;
|
||||
selected_entity.transform.dirty = true;
|
||||
e.transform.position = entity_position;
|
||||
e.transform.dirty = true;
|
||||
}
|
||||
|
||||
entity_position := engine.editor.transform_gizmo.actual_entity_position + position_change;
|
||||
engine.editor.transform_gizmo.actual_entity_position = entity_position;
|
||||
set_position(*engine.editor.transform_gizmo.transform, entity_position);
|
||||
}
|
||||
|
||||
@@ -670,8 +701,16 @@ intersect_rotation_gizmo :: (ray: Ray) -> Transform_Axis, Vector3 {
|
||||
}
|
||||
|
||||
update_gizmo_buffers :: () {
|
||||
position : Vector3;
|
||||
for e: engine.editor.selected_entities {
|
||||
position += e.transform.position;
|
||||
}
|
||||
|
||||
position /= cast(float)engine.editor.selected_entities.count;
|
||||
|
||||
entity := engine.editor.selected_entities[0];
|
||||
engine.editor.transform_gizmo.transform.position = entity.transform.position;
|
||||
|
||||
engine.editor.transform_gizmo.transform.position = position;
|
||||
engine.editor.transform_gizmo.transform.orientation = ifx engine.editor.transform_gizmo.space == .LOCAL then entity.transform.orientation else .{0,0,0,1};
|
||||
update_matrix(*engine.editor.transform_gizmo.transform);
|
||||
|
||||
@@ -689,7 +728,7 @@ update_gizmo_buffers :: () {
|
||||
}
|
||||
|
||||
render_transform_gizmo :: () {
|
||||
if engine.editor.selected_entities.count == 1 {
|
||||
if engine.editor.selected_entities.count > 0 {
|
||||
update_gizmo_buffers();
|
||||
renderer := engine.renderer;
|
||||
push_cmd_set_draw_mode(renderer, .FILL);
|
||||
|
||||
@@ -24,6 +24,8 @@ pick_scene_view_at :: (camera: Camera, coordinates: Vector2) {
|
||||
engine.editor.selected_entities.count = 0;
|
||||
}
|
||||
array_add(*engine.editor.selected_entities, hit_entity);
|
||||
} else {
|
||||
array_unordered_remove_by_value(*engine.editor.selected_entities, hit_entity);
|
||||
}
|
||||
} else {
|
||||
engine.editor.selected_entities.count = 0;
|
||||
@@ -174,7 +176,7 @@ base_editor_update :: () {
|
||||
if engine.editor.focused_widget == null && engine.mode == .EDITING {
|
||||
engine.editor.should_check_entities = true;
|
||||
|
||||
if engine.editor.selected_entities.count == 1 {
|
||||
if engine.editor.selected_entities.count > 0 {
|
||||
entity := engine.editor.selected_entities[0];
|
||||
gizmo_scale := distance(entity.transform.position, engine.editor.camera.position) * 0.1 * 0.5;
|
||||
engine.editor.transform_gizmo.uniform_gizmo_scale = gizmo_scale;
|
||||
|
||||
@@ -228,7 +228,9 @@ generate_member_ui_imgui :: (type: *Type_Info_Struct, builder: *String_Builder,
|
||||
} else if info_struct.name == "Vector3" {
|
||||
print_to_builder(builder, "\tImGui.DragFloat3(tprint_c(\"%\"), *e.%.component);\n", new_path, new_path);
|
||||
} else if info_struct.name == "Color" || info_struct.name == "Vector4" {
|
||||
print_to_builder(builder, "\tImGui.ColorEdit4(tprint_c(\"%\"), *e.%.component);\n", new_path, new_path);
|
||||
print_to_builder(builder, "\tsrgb_color := linear_to_srgb(e.%);\n", new_path);
|
||||
print_to_builder(builder, "\tImGui.ColorEdit4(tprint_c(\"%\"), *srgb_color.component);\n", new_path);
|
||||
print_to_builder(builder, "\te.% = srgb_to_linear(srgb_color);\n", new_path);
|
||||
} else {
|
||||
generate_member_ui_imgui(info_struct, builder, new_path);
|
||||
}
|
||||
|
||||
@@ -46,9 +46,12 @@ Engine_Core :: struct {
|
||||
on_scene_loaded: (*Scene, Engine_Mode);
|
||||
on_pre_scene_loaded: (*Scene, Engine_Mode);
|
||||
on_pre_scene_unloaded: (*Scene);
|
||||
|
||||
#if PHYSICS {
|
||||
on_trigger_enter: (*Entity, *Entity);
|
||||
on_trigger_exit: (*Entity, *Entity);
|
||||
}
|
||||
}
|
||||
|
||||
paused: bool;
|
||||
|
||||
@@ -104,6 +107,7 @@ coven_init :: (window_title: string, window_width: u32, window_height: u32, full
|
||||
}
|
||||
|
||||
coven_run :: (game_update_proc: (float), game_editor_update_proc: (float), game_update_post_physics_proc: (float)) {
|
||||
#if EDITOR {
|
||||
if engine.current_scene == null && engine.automatically_load_last_opened_scene {
|
||||
last_opened_scene := get_last_opened_scene_file();
|
||||
if last_opened_scene.count > 0 {
|
||||
@@ -111,6 +115,7 @@ coven_run :: (game_update_proc: (float), game_editor_update_proc: (float), game_
|
||||
free(last_opened_scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdl_window := cast(*SDL_Window_Type)engine.window;
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
PHYSX_DEFAULT_SIMULATION_SHAPE_FLAGS :: cast(u8)(PhysX.PxShapeFlags.Visualization | PhysX.PxShapeFlags.SceneQueryShape | PhysX.PxShapeFlags.SimulationShape);
|
||||
PHYSX_DEFAULT_TRIGGER_SHAPE_FLAGS :: cast(u8)(PhysX.PxShapeFlags.Visualization | PhysX.PxShapeFlags.SceneQueryShape | PhysX.PxShapeFlags.TriggerShape);
|
||||
|
||||
PHYSX_GRAVITY :: Vector3.{0, -9.81, 0};
|
||||
|
||||
PhysX_Handle :: #type, distinct u32;
|
||||
|
||||
PhysX_Actor_Type :: enum {
|
||||
STATIC;
|
||||
DYNAMIC;
|
||||
CHARACTER;
|
||||
}
|
||||
|
||||
PhysX_Actor :: struct {
|
||||
@@ -16,12 +19,15 @@ PhysX_Actor :: struct {
|
||||
union {
|
||||
static: *PhysX.PxRigidStatic;
|
||||
dynamic: *PhysX.PxRigidDynamic;
|
||||
controller: *PhysX.PxController;
|
||||
}
|
||||
}
|
||||
|
||||
PhysX_Scene :: struct {
|
||||
scene: *PhysX.PxScene;
|
||||
actors : PArray(PhysX_Actor, PhysX_Handle);
|
||||
|
||||
controller_manager: *PhysX.PxControllerManager;
|
||||
}
|
||||
|
||||
init_physx :: () {
|
||||
@@ -43,6 +49,8 @@ init_physx :: () {
|
||||
tolerance_scale.speed = 10;
|
||||
physics = PhysX.PxCreatePhysics(PhysX.PX_PHYSICS_VERSION, foundation, *tolerance_scale, true, pvd, null);
|
||||
|
||||
cooking_params = PhysX.PxCookingParams_new(*tolerance_scale);
|
||||
|
||||
dispatcher = PhysX.PxDefaultCpuDispatcherCreate(2);
|
||||
material = PhysX.PxPhysics_createMaterial(physics, 0.0, 0.0, 0.6);
|
||||
|
||||
@@ -75,10 +83,46 @@ on_physx_trigger :: (_u: *void, pair: *PhysX.PxTriggerPair, count: u32) #c_call
|
||||
}
|
||||
|
||||
tick_physx :: (scene: *PhysX_Scene, dt: float) {
|
||||
// Move all character controllers first
|
||||
filter_data := PhysX.PxFilterData_new();
|
||||
filter := PhysX.PxControllerFilters_new(*filter_data, null, null);
|
||||
for e: engine.current_scene.entities {
|
||||
if e.flags & .PHYSICS {
|
||||
if e.physics.physx_handle != 0 {
|
||||
physx_actor := parray_get(*engine.current_scene.physx_scene.actors, e.physics.physx_handle);
|
||||
if physx_actor {
|
||||
if physx_actor.type == .CHARACTER {
|
||||
vel := e.physics.velocity + PHYSX_GRAVITY * dt;;
|
||||
movement := vel * dt;
|
||||
print("Velocity %\n", movement);
|
||||
flags := PhysX.PxController_move(physx_actor.controller, *movement, 0.0, dt, *filter, null);
|
||||
new_position := PhysX.PxController_getPosition(physx_actor.controller);
|
||||
position := Vector3.{xx new_position.x, xx new_position.y, xx new_position.z};
|
||||
e.physics.velocity = (position - e.transform.position) / dt;
|
||||
set_position(e, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Simulate
|
||||
PhysX.PxScene_simulate(scene.scene, dt, null, null, 0, true);
|
||||
|
||||
// Sync results back
|
||||
PhysX.PxScene_fetchResults(scene.scene, true, null);
|
||||
}
|
||||
|
||||
//custom_filter_shader :: (attributes0: u32, filterData0: PhysX.PxFilterData, attributes1: u32, filterData1: PhysX.PxFilterData, pairFlags: *PhysX.PxPairFlags, constantBlock: *void, constantBlockSize: u32) -> PhysX.PxFilterFlags #c_call {
|
||||
// pairFlags.* = PhysX.PxPairFlags.ContactDefault;
|
||||
// return PhysX.PxFilterFlags.Default;
|
||||
//}
|
||||
|
||||
custom_filter_shader :: (attributes0: *u32, filterData0: *PhysX.PxFilterData, attributes1: *u32, filterData1: *PhysX.PxFilterData, pairFlags: *PhysX.PxPairFlags) -> u16 #c_call {
|
||||
pairFlags.* = PhysX.PxPairFlags.ContactDefault;
|
||||
return xx PhysX.PxFilterFlags.Default;
|
||||
}
|
||||
|
||||
init_physx_scene :: (game_scene: *Scene) {
|
||||
tolerance_scale : PhysX.PxTolerancesScale;
|
||||
tolerance_scale.length = 1;
|
||||
@@ -89,7 +133,10 @@ init_physx_scene :: (game_scene: *Scene) {
|
||||
|
||||
scene_desc.cpuDispatcher = xx dispatcher;
|
||||
scene_desc.simulationEventCallback = event_callback;
|
||||
PhysX.set_default_filter_shader(*scene_desc);
|
||||
PhysX.set_custom_filter_shader(*scene_desc, PhysX.create_custom_filter_shader(custom_filter_shader));
|
||||
//scene_desc.filterShader = custom_filter_shader;//
|
||||
//scene_desc.filterShaderData = null;
|
||||
//scene_desc.filterShaderDataSize = 0;
|
||||
|
||||
scene := PhysX.PxPhysics_createScene(physics, *scene_desc);
|
||||
|
||||
@@ -105,6 +152,7 @@ init_physx_scene :: (game_scene: *Scene) {
|
||||
physx_scene.scene = scene;
|
||||
physx_scene.actors.data.allocator = game_scene.allocator;
|
||||
physx_scene.actors.indices.allocator = game_scene.allocator;
|
||||
physx_scene.controller_manager = PhysX.PxCreateControllerManager(scene, false);
|
||||
|
||||
game_scene.physx_scene = physx_scene;
|
||||
}
|
||||
@@ -119,9 +167,19 @@ pre_physx_sync :: (game_scene: *Scene) {
|
||||
if it.physics.physx_handle != 0 {
|
||||
// @Incomplete: Update the transform!
|
||||
physx_actor := parray_get(*game_scene.physx_scene.actors, it.physics.physx_handle);
|
||||
if physx_actor.type == .DYNAMIC {
|
||||
if physx_actor.type == {
|
||||
case .DYNAMIC; {
|
||||
pose := PhysX.PxTransform_new(*it.transform.position, *it.transform.orientation);
|
||||
PhysX.PxRigidActor_setGlobalPose(physx_actor.dynamic, *pose, true);
|
||||
// @Incomplete: Might wanna do this differently or at least not every frame?
|
||||
// We could potentially cache the last saved position and not update the pose, if PhysX is synced up
|
||||
PhysX.PxRigidDynamic_setLinearVelocity(physx_actor.dynamic, *it.physics.velocity, true);
|
||||
}
|
||||
case .STATIC; {
|
||||
pose := PhysX.PxTransform_new(*it.transform.position, *it.transform.orientation);
|
||||
PhysX.PxRigidActor_setGlobalPose(physx_actor.static, *pose, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
create_physx_actor(it);
|
||||
}
|
||||
@@ -152,6 +210,33 @@ post_physx_sync :: (game_scene: *Scene) {
|
||||
}
|
||||
|
||||
create_physx_actor :: (e: *Entity) {
|
||||
if e.physics.type == .CHARACTER {
|
||||
material := PhysX.PxPhysics_createMaterial(physics, e.physics.static_friction, e.physics.dynamic_friction, e.physics.restitution);
|
||||
|
||||
desc := PhysX.PxCapsuleControllerDesc_new_alloc();
|
||||
desc.height = e.physics.character.height;
|
||||
desc.radius = e.physics.character.radius;
|
||||
desc.stepOffset = 0.2;
|
||||
desc.slopeLimit = cos(PI * 0.25);
|
||||
desc.contactOffset = desc.stepOffset * 0.1;
|
||||
desc.material = material;
|
||||
desc.position = .{xx e.transform.position.x, xx e.transform.position.y, xx e.transform.position.z};
|
||||
desc.density = 40.0;
|
||||
desc.userData = null;
|
||||
|
||||
scene := engine.current_scene.physx_scene;
|
||||
controller := PhysX.PxControllerManager_createController(scene.controller_manager, desc);
|
||||
PhysX.PxCapsuleControllerDesc_delete(desc);
|
||||
|
||||
physics_actor : PhysX_Actor;
|
||||
physics_actor.type = .CHARACTER;
|
||||
physics_actor.sync_rotation_from_physx = false;//e.physics.type != .CAPSULE; // @Incomplete
|
||||
|
||||
physics_actor.controller = controller;
|
||||
|
||||
e.physics.physx_handle = parray_add(*e.scene.physx_scene.actors, physics_actor);
|
||||
e.physics.enabled = true;
|
||||
} else {
|
||||
actor : *PhysX.PxRigidActor;
|
||||
transform : PhysX.PxTransform;
|
||||
position := e.transform.position + e.physics.offset;
|
||||
@@ -201,10 +286,121 @@ create_physx_actor :: (e: *Entity) {
|
||||
case .CAPSULE; {
|
||||
geo = PhysX.PxCapsuleGeometry_new(e.physics.capsule.radius, e.physics.capsule.half_height-e.physics.capsule.radius);
|
||||
}
|
||||
case .CONVEX_MESH; {
|
||||
if e.flags & .RENDERABLE {
|
||||
points : [..] Vector3;
|
||||
points.allocator = temp;
|
||||
indices : [..] u32;
|
||||
indices.allocator = temp;
|
||||
|
||||
model := get_model_by_handle(e.renderable.model);
|
||||
|
||||
for node, node_index: model.nodes {
|
||||
render_data := e.renderable.nodes[node_index];
|
||||
|
||||
success, inv_matrix := inverse(e.transform.model_matrix);
|
||||
// We need to undo the local to world part of every world matrix
|
||||
matrix := inv_matrix * render_data.transform.world_matrix;
|
||||
|
||||
if node.meshes.count > 0 {
|
||||
for m, mi: node.meshes {
|
||||
index_start : u32 = xx indices.count;
|
||||
mesh := parray_get(*engine.renderer.meshes, m);
|
||||
for v: mesh.positions {
|
||||
array_add(*points, v);//transform_position(v, matrix));
|
||||
}
|
||||
|
||||
for i: mesh.indices {
|
||||
array_add(*indices, index_start + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mesh_desc := PhysX.PxConvexMeshDesc_new();
|
||||
mesh_desc.points.count = xx points.count;
|
||||
mesh_desc.points.stride = size_of(Vector3);
|
||||
mesh_desc.points.data = points.data;
|
||||
|
||||
mesh_desc.polygons.count = cast(u32)(indices.count / 3);
|
||||
mesh_desc.polygons.stride = 3 * size_of(u32);
|
||||
mesh_desc.polygons.data = indices.data;
|
||||
|
||||
if !PhysX.PxValidateConvexMesh(*cooking_params, *mesh_desc) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
stream : PhysX.PxOutputStream;
|
||||
callback := PhysX.PxGetStandaloneInsertionCallback();
|
||||
//read_buffer : PhysX.PxDefaultMemoryInputData_new(;
|
||||
cond : s32;
|
||||
mesh := PhysX.PxCreateConvexMesh(*cooking_params, *mesh_desc, callback, null);
|
||||
scale := PhysX.PxMeshScale_new(*e.transform.scale);
|
||||
geo = PhysX.PxConvexMeshGeometry_new(mesh, *scale, 0);
|
||||
}
|
||||
}
|
||||
case .TRIANGLE_MESH; {
|
||||
if e.flags & .RENDERABLE {
|
||||
points : [..] Vector3;
|
||||
points.allocator = temp;
|
||||
indices : [..] u32;
|
||||
indices.allocator = temp;
|
||||
|
||||
model := get_model_by_handle(e.renderable.model);
|
||||
|
||||
for node, node_index: model.nodes {
|
||||
render_data := e.renderable.nodes[node_index];
|
||||
|
||||
success, inv_matrix := inverse(e.transform.model_matrix);
|
||||
// We need to undo the local to world part of every world matrix
|
||||
matrix := inv_matrix * render_data.transform.world_matrix;
|
||||
|
||||
if node.meshes.count > 0 {
|
||||
for m, mi: node.meshes {
|
||||
index_start : u32 = xx indices.count;
|
||||
mesh := parray_get(*engine.renderer.meshes, m);
|
||||
for v: mesh.positions {
|
||||
array_add(*points, transform_position(v, matrix));
|
||||
}
|
||||
|
||||
for i: mesh.indices {
|
||||
array_add(*indices, index_start + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mesh_desc : PhysX.PxTriangleMeshDesc;
|
||||
mesh_desc.points.count = xx points.count;
|
||||
mesh_desc.points.stride = size_of(Vector3);
|
||||
mesh_desc.points.data = points.data;
|
||||
|
||||
mesh_desc.triangles.count = cast(u32)(indices.count / 3);
|
||||
mesh_desc.triangles.stride = 3 * size_of(u32);
|
||||
mesh_desc.triangles.data = indices.data;
|
||||
|
||||
//if !PhysX.PxValidateTriangleMesh(*cooking_params, *mesh_desc) {
|
||||
// assert(false);
|
||||
//}
|
||||
|
||||
callback := PhysX.PxGetStandaloneInsertionCallback();
|
||||
mesh := PhysX.PxCreateTriangleMesh(*cooking_params, *mesh_desc, callback, null);
|
||||
scale := PhysX.PxMeshScale_new(*e.transform.scale);
|
||||
geo = PhysX.PxTriangleMeshGeometry_new(mesh, *scale, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shape := PhysX.PxPhysics_createShape(physics, geo, material, false, ifx e.physics.trigger then PHYSX_DEFAULT_TRIGGER_SHAPE_FLAGS else PHYSX_DEFAULT_SIMULATION_SHAPE_FLAGS);
|
||||
|
||||
// Setup layers
|
||||
filter_data := PhysX.PxFilterData_new();
|
||||
filter_data.word0 = 1;
|
||||
filter_data.word1 = 1;
|
||||
filter_data.word2 = 1;
|
||||
filter_data.word3 = 1;
|
||||
|
||||
PhysX.PxShape_setSimulationFilterData(shape, *filter_data);
|
||||
PhysX.PxShape_setQueryFilterData(shape, *filter_data);
|
||||
|
||||
PhysX.PxRigidActor_attachShape(actor, shape);
|
||||
|
||||
if e.physics.dynamic {
|
||||
@@ -229,6 +425,7 @@ create_physx_actor :: (e: *Entity) {
|
||||
e.physics.physx_handle = parray_add(*e.scene.physx_scene.actors, physics_actor);
|
||||
e.physics.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Hit :: struct {
|
||||
|
||||
@@ -246,6 +443,7 @@ PhysX :: #import "PhysX";
|
||||
#scope_file
|
||||
|
||||
physics : *PhysX.PxPhysics;
|
||||
cooking_params: PhysX.PxCookingParams;
|
||||
material : *PhysX.PxMaterial;
|
||||
default_allocator : PhysX.PxAllocatorCallback;
|
||||
default_error_callback : PhysX.PxErrorCallback;
|
||||
|
||||
@@ -1115,7 +1115,7 @@ create_backend_render_target :: (using backend: *D3D11_Backend, width: u32, heig
|
||||
texture_desc.Height = height;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = .DXGI_FORMAT_R32G32B32A32_FLOAT; // @Incomplete
|
||||
texture_desc.Format = .DXGI_FORMAT_R16G16B16A16_FLOAT; // @Incomplete
|
||||
texture_desc.SampleDesc.Count = 1;
|
||||
texture_desc.Usage = .D3D11_USAGE_DEFAULT;
|
||||
texture_desc.BindFlags = D3D11_BIND_FLAG.RENDER_TARGET | D3D11_BIND_FLAG.SHADER_RESOURCE;
|
||||
|
||||
@@ -624,6 +624,7 @@ Renderer :: struct {
|
||||
|
||||
default_pipelines : struct {
|
||||
message_text : Pipeline_State_Handle;
|
||||
entity_pipeline : Pipeline_State_Handle;
|
||||
}
|
||||
|
||||
default_samplers : struct {
|
||||
@@ -684,6 +685,7 @@ create_renderer :: (window: *Window) -> *Renderer {
|
||||
init_freetype();
|
||||
init_default_meshes();
|
||||
init_trigger_line_rendering();
|
||||
init_default_pipelines();
|
||||
|
||||
array_reserve(*engine.renderer.command_buffer.commands, 4096);
|
||||
|
||||
@@ -698,36 +700,36 @@ create_renderer :: (window: *Window) -> *Renderer {
|
||||
}
|
||||
|
||||
init_default_pipelines :: () {
|
||||
{
|
||||
vs := create_vertex_shader(renderer, "../modules/Coven/shaders/font.hlsl", "VS");
|
||||
ps := create_pixel_shader(renderer, "../modules/Coven/shaders/font.hlsl", "PS");
|
||||
//{
|
||||
// vs := create_vertex_shader(renderer, "../modules/Coven/shaders/font.hlsl", "VS");
|
||||
// ps := create_pixel_shader(renderer, "../modules/Coven/shaders/font.hlsl", "PS");
|
||||
|
||||
layout : [3] Vertex_Data_Info;
|
||||
layout[0] = .{0,.POSITION2D, 0};
|
||||
layout[1] = .{0,.TEXCOORD0, 0};
|
||||
layout[2] = .{0,.COLOR_WITH_ALPHA, 0};
|
||||
// layout : [3] Vertex_Data_Info;
|
||||
// layout[0] = .{0,.POSITION2D, 0};
|
||||
// layout[1] = .{0,.TEXCOORD0, 0};
|
||||
// layout[2] = .{0,.COLOR_WITH_ALPHA, 0};
|
||||
|
||||
params : [2] Shader_Parameter;
|
||||
params[0].shader = .PIXEL;
|
||||
params[0].type = .SAMPLER;
|
||||
params[0].name = "ss";
|
||||
params[0].slot = 0;
|
||||
params[0].mapping = .CLAMP_SAMPLER;
|
||||
// params : [2] Shader_Parameter;
|
||||
// params[0].shader = .PIXEL;
|
||||
// params[0].type = .SAMPLER;
|
||||
// params[0].name = "ss";
|
||||
// params[0].slot = 0;
|
||||
// params[0].mapping = .CLAMP_SAMPLER;
|
||||
|
||||
params[1].shader = .PIXEL;
|
||||
params[1].type = .TEXTURE;
|
||||
params[1].name = "tex";
|
||||
params[1].slot = 1;
|
||||
// params[1].shader = .PIXEL;
|
||||
// params[1].type = .TEXTURE;
|
||||
// params[1].name = "tex";
|
||||
// params[1].slot = 1;
|
||||
|
||||
engine.renderer.default_pipelines.message_text = create_pipeline_state(renderer, vs, ps, layout, params, blend_type=.TRANSPARENT);
|
||||
}
|
||||
// engine.renderer.default_pipelines.message_text = create_pipeline_state(renderer, vs, ps, layout, params, blend_type=.TRANSPARENT);
|
||||
//}
|
||||
|
||||
{
|
||||
vs := create_vertex_shader_from_source(engine.renderer, FALLBACK_SHADER, "VS", mesh_data_types = .[.POSITION]);
|
||||
ps := create_pixel_shader_from_source(engine.renderer, FALLBACK_SHADER, "PS");
|
||||
//{
|
||||
// vs := create_vertex_shader_from_source(engine.renderer, "fallback", FALLBACK_SHADER, "VS", mesh_data_types = .[.POSITION]);
|
||||
// ps := create_pixel_shader_from_source(engine.renderer, "fallback", FALLBACK_SHADER, "PS");
|
||||
|
||||
projectile_pipeline = create_pipeline_state2(engine.renderer, vs, ps, blend_type=.OPAQUE);
|
||||
}
|
||||
// projectile_pipeline = create_pipeline_state2(engine.renderer, vs, ps, blend_type=.OPAQUE);
|
||||
//}
|
||||
}
|
||||
|
||||
init_default_meshes :: () {
|
||||
@@ -736,20 +738,20 @@ init_default_meshes :: () {
|
||||
// Since this is used for sprites, we want the origin to be in the center in x, but at the bottom in y
|
||||
mesh : Mesh;
|
||||
mesh.name = copy_string("Plane");
|
||||
array_add(*mesh.positions, .{1, 0, 1});
|
||||
array_add(*mesh.positions, .{-1, 0, -1});
|
||||
array_add(*mesh.positions, .{1, 0, -1});
|
||||
array_add(*mesh.positions, .{-1, 0, 1});
|
||||
array_add(*mesh.positions, .{0.5, 0, 0.5});
|
||||
array_add(*mesh.positions, .{-0.5, 0, -0.5});
|
||||
array_add(*mesh.positions, .{0.5, 0, -0.5});
|
||||
array_add(*mesh.positions, .{-0.5, 0, 0.5});
|
||||
|
||||
array_add(*mesh.normals, .{0, 1, 0});
|
||||
array_add(*mesh.normals, .{0, 1, 0});
|
||||
array_add(*mesh.normals, .{0, 1, 0});
|
||||
array_add(*mesh.normals, .{0, 1, 0});
|
||||
|
||||
array_add(*mesh.texcoords, .{1, 0});
|
||||
array_add(*mesh.texcoords, .{0, 1});
|
||||
array_add(*mesh.texcoords, .{1, 1});
|
||||
array_add(*mesh.texcoords, .{0, 0});
|
||||
array_add(*mesh.texcoords, .{1, 0});
|
||||
array_add(*mesh.texcoords, .{0, 1});
|
||||
|
||||
array_add(*mesh.indices, 2);
|
||||
array_add(*mesh.indices, 1);
|
||||
@@ -862,6 +864,10 @@ deinit_renderer :: (renderer: *Renderer) {
|
||||
deinit_backend(engine.renderer.backend);
|
||||
}
|
||||
|
||||
set_default_entity_pipeline :: (pipeline: Pipeline_State_Handle) {
|
||||
engine.renderer.default_pipelines.entity_pipeline = pipeline;
|
||||
}
|
||||
|
||||
get_shader :: (handle: Shader_Handle) -> Shader {
|
||||
assert(handle - 1 < xx engine.renderer.shaders.count);
|
||||
return engine.renderer.shaders[handle-1];
|
||||
@@ -1689,6 +1695,55 @@ render :: () {
|
||||
// #load "ui.jai";
|
||||
//}
|
||||
|
||||
render_default_renderable_entities :: () {
|
||||
for e: engine.current_scene.entities {
|
||||
if e.enabled && e.flags & .RENDERABLE && e.renderable.use_default_pipeline {
|
||||
render_entity(e, engine.renderer.default_pipelines.entity_pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_entity :: (e: *Entity, pipeline: Pipeline_State_Handle) {
|
||||
if e.renderable.type == {
|
||||
case .MODEL; {
|
||||
model := get_model_by_handle(e.renderable.model);
|
||||
if model == null return;
|
||||
|
||||
for node, node_index: model.nodes {
|
||||
render_data := e.renderable.nodes[node_index];
|
||||
if !render_data.enabled continue;
|
||||
|
||||
if node.meshes.count > 0 {
|
||||
for m, mi: node.meshes {
|
||||
push_cmd_set_pipeline_state(engine.renderer, pipeline);
|
||||
push_cmd_set_constant_buffer(engine.renderer, 1, engine.directional_light_buffer, .VERTEX);
|
||||
push_cmd_set_constant_buffer(engine.renderer, 1, engine.directional_light_buffer, .PIXEL);
|
||||
|
||||
push_cmd_set_constant_buffer(engine.renderer, 2, render_data.transform_buffer, .VERTEX);
|
||||
push_cmd_set_constant_buffer(engine.renderer, 3, render_data.material_buffer, .PIXEL);
|
||||
|
||||
if node.num_bones > 0 {
|
||||
push_cmd_set_constant_buffer(engine.renderer, 4, render_data.bone_buffers[mi], .VERTEX);
|
||||
}
|
||||
|
||||
mesh := parray_get(*engine.renderer.meshes, m);
|
||||
|
||||
vb := get_mesh_vb(mesh);
|
||||
push_cmd_set_vertex_buffer(engine.renderer, vb);
|
||||
|
||||
if mesh.ib != 0 {
|
||||
push_cmd_set_index_buffer(engine.renderer, mesh.ib);
|
||||
push_cmd_draw_indexed(engine.renderer, mesh.indices.count);
|
||||
} else {
|
||||
push_cmd_draw(engine.renderer, mesh.positions.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#scope_module
|
||||
#load "dx11_renderer.jai";
|
||||
|
||||
|
||||
@@ -61,8 +61,11 @@ init_trigger_line_rendering :: () {
|
||||
}
|
||||
|
||||
render_trigger_lines :: () {
|
||||
#if PHYSICS {
|
||||
for e: engine.current_scene.entities {
|
||||
if e.physics.type == .BOX {
|
||||
if !e.physics.render_collider continue;
|
||||
|
||||
color := Color.{0,0,1,1};//e.collider.aabb_color;
|
||||
aabb := AABB.{-e.physics.box.half_extent, e.physics.box.half_extent};
|
||||
|
||||
@@ -86,3 +89,4 @@ render_trigger_lines :: () {
|
||||
|
||||
render_lines();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user