mirror of
https://github.com/armory3d/armorpaint.git
synced 2026-10-02 02:54:34 +08:00
paint: cleanup
This commit is contained in:
+11
-10
@@ -343,10 +343,10 @@ void base_update(void *_) {
|
||||
|
||||
if (g_context->tool == TOOL_TYPE_CURSOR && context_in_3d_view()) {
|
||||
if (keyboard_down("control") && keyboard_started("d")) {
|
||||
sim_duplicate();
|
||||
util_mesh_duplicate();
|
||||
}
|
||||
if (keyboard_started("delete")) {
|
||||
sim_delete();
|
||||
util_mesh_delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,17 +382,18 @@ void base_update(void *_) {
|
||||
camera_update(NULL);
|
||||
|
||||
if (g_config->workspace == WORKSPACE_PLAYER) {
|
||||
sim_init();
|
||||
if (!sim_running) {
|
||||
sim_play();
|
||||
}
|
||||
sim_update();
|
||||
player_running = true;
|
||||
render_path_raytrace_ready = false;
|
||||
trait_update();
|
||||
physics_world_update();
|
||||
iron_delay_idle_sleep();
|
||||
}
|
||||
else if (sim_running) {
|
||||
sim_stop();
|
||||
else if (player_running) {
|
||||
player_running = false;
|
||||
trait_stop();
|
||||
}
|
||||
|
||||
if (sim_running || tab_timeline_playing) {
|
||||
if (player_running || tab_timeline_playing) {
|
||||
if (g_context->ddirty < 0) {
|
||||
g_context->ddirty = 0;
|
||||
}
|
||||
|
||||
+11
-16
@@ -579,21 +579,6 @@ void ui_view2d_update(void *_);
|
||||
void ui_view2d_play_sound();
|
||||
void ui_view2d_stop_sound();
|
||||
void make_picking_run(node_shader_t *kong);
|
||||
void sim_init();
|
||||
void sim_update();
|
||||
void sim_play();
|
||||
void sim_stop();
|
||||
void sim_add_body(object_t *o, physics_shape_t shape, f32 mass);
|
||||
void sim_physics_clear();
|
||||
void sim_physics_store(object_t *o, i32 shape, f32 mass);
|
||||
void sim_physics_set(object_t *o, i32 shape, f32 mass);
|
||||
void sim_physics_set_mass(object_t *o, f32 mass);
|
||||
i32 sim_physics_get_shape(object_t *o);
|
||||
f32 sim_physics_get_mass(object_t *o);
|
||||
void sim_physics_apply_stage(stage_t *stage);
|
||||
mesh_object_t *sim_duplicate_object(mesh_object_t *so);
|
||||
void sim_duplicate();
|
||||
void sim_delete();
|
||||
void trait_update();
|
||||
void trait_stop();
|
||||
void trait_third_person_controller_init(char *object);
|
||||
@@ -683,6 +668,9 @@ void util_mesh_bevel(f32 amount);
|
||||
void util_mesh_subdivide();
|
||||
i32 util_mesh_atlas_stride();
|
||||
i32 util_mesh_atlas_slot(object_t *object);
|
||||
mesh_object_t *util_mesh_duplicate_object(mesh_object_t *so);
|
||||
void util_mesh_duplicate();
|
||||
void util_mesh_delete();
|
||||
void ui_header_init();
|
||||
void ui_header_render_ui();
|
||||
void ui_header_draw_tool_properties();
|
||||
@@ -845,8 +833,15 @@ void tab_meshes_on_material_reordered(i32 old_index, i32 ne
|
||||
void tab_meshes_draw_transform_loc(mesh_object_t *o, char *ns);
|
||||
void tab_meshes_draw_transform_rot(mesh_object_t *o, char *ns);
|
||||
void tab_meshes_draw_transform_scale(mesh_object_t *o, char *ns);
|
||||
void util_particle_init_physics();
|
||||
void util_particle_init_mesh();
|
||||
void util_particle_update();
|
||||
void util_physics_clear();
|
||||
void util_physics_store(object_t *o, i32 shape, f32 mass);
|
||||
void util_physics_set(object_t *o, i32 shape, f32 mass);
|
||||
void util_physics_set_mass(object_t *o, f32 mass);
|
||||
i32 util_physics_get_shape(object_t *o);
|
||||
f32 util_physics_get_mass(object_t *o);
|
||||
void util_physics_apply_stage(stage_t *stage);
|
||||
void tab_layers_apply_filter(i32 filter);
|
||||
void tab_layers_draw(i32 *htab);
|
||||
void tab_layers_remap_layer_pointers(ui_node_t_array_t *nodes, i32_imap_t *pointer_map);
|
||||
|
||||
@@ -198,7 +198,7 @@ bool ui_view2d_tiled_show = false;
|
||||
bool ui_view2d_grid_redraw = true;
|
||||
i32 ui_view2d_tab;
|
||||
sound_t *ui_view2d_sound_playing = NULL;
|
||||
bool sim_running = false;
|
||||
bool player_running = false;
|
||||
bool viewport_recording = false;
|
||||
bool node_shader_dump_to_script = false;
|
||||
node_shader_context_t *parser_material_con;
|
||||
|
||||
@@ -351,8 +351,8 @@ void export_arm_run_project() {
|
||||
g_project->mesh_physics_masses = f32_array_create(g_project->_->paint_objects->length);
|
||||
for (i32 i = 0; i < g_project->mesh_physics_shapes->length; ++i) {
|
||||
object_t *o = g_project->_->paint_objects->buffer[i]->base;
|
||||
g_project->mesh_physics_shapes->buffer[i] = sim_physics_get_shape(o); // -1 = no physics
|
||||
g_project->mesh_physics_masses->buffer[i] = sim_physics_get_mass(o);
|
||||
g_project->mesh_physics_shapes->buffer[i] = util_physics_get_shape(o); // -1 = no physics
|
||||
g_project->mesh_physics_masses->buffer[i] = util_physics_get_mass(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -958,7 +958,7 @@ void import_arm_run_project(char *path) {
|
||||
continue; // No physics
|
||||
}
|
||||
f32 mass = g_project->mesh_physics_masses != NULL && i < g_project->mesh_physics_masses->length ? g_project->mesh_physics_masses->buffer[i] : 0.0;
|
||||
sim_physics_store(g_project->_->paint_objects->buffer[i]->base, shape, mass);
|
||||
util_physics_store(g_project->_->paint_objects->buffer[i]->base, shape, mass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,7 +972,7 @@ void import_arm_run_project(char *path) {
|
||||
tab_stages_apply(g_project->stages->buffer[0]);
|
||||
}
|
||||
else {
|
||||
sim_physics_apply_stage(NULL);
|
||||
util_physics_apply_stage(NULL);
|
||||
}
|
||||
|
||||
sys_notify_on_next_frame(&import_arm_run_project_on_next_frame, NULL);
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
#include "util/util_nodes.c"
|
||||
#include "util/util_particle.c"
|
||||
#include "util/util_path.c"
|
||||
#include "util/util_physics.c"
|
||||
#include "util/util_raycast.c"
|
||||
#include "util/util_render.c"
|
||||
#include "util/util_resize.c"
|
||||
@@ -226,7 +227,6 @@
|
||||
#include "plugin.c"
|
||||
#include "project.c"
|
||||
#include "resource.c"
|
||||
#include "sim.c"
|
||||
#include "strings.c"
|
||||
#include "trait.c"
|
||||
#include "translator.c"
|
||||
|
||||
@@ -738,7 +738,7 @@ object_t *script_object_duplicate(object_t *o) {
|
||||
gpu_texture_t *current;
|
||||
bool in_use;
|
||||
script_gpu_begin(¤t, &in_use);
|
||||
mesh_object_t *dup = sim_duplicate_object(o->ext);
|
||||
mesh_object_t *dup = util_mesh_duplicate_object(o->ext);
|
||||
script_gpu_end(current, in_use);
|
||||
|
||||
g_context->ddirty = 2;
|
||||
@@ -781,7 +781,7 @@ void script_physics_set_shape(object_t *o, i32 shape) {
|
||||
}
|
||||
|
||||
bool dynamic = shape == PHYSICS_SHAPE_BOX || shape == PHYSICS_SHAPE_SPHERE;
|
||||
sim_physics_set(o, shape, shape < 0 ? 0.0 : (dynamic ? 1.0 : 0.0));
|
||||
util_physics_set(o, shape, shape < 0 ? 0.0 : (dynamic ? 1.0 : 0.0));
|
||||
g_project->mesh_physics_shapes = i32_array_create(0);
|
||||
}
|
||||
|
||||
@@ -789,7 +789,7 @@ void script_physics_set_mass(object_t *o, f32 mass) {
|
||||
if (o == NULL) {
|
||||
return;
|
||||
}
|
||||
sim_physics_set_mass(o, mass);
|
||||
util_physics_set_mass(o, mass);
|
||||
g_project->mesh_physics_shapes = i32_array_create(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ void project_cleanup() {
|
||||
data_delete_texture(a->file);
|
||||
}
|
||||
|
||||
sim_physics_clear();
|
||||
util_physics_clear();
|
||||
}
|
||||
|
||||
void project_new_on_next_frame(void *_) {
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
|
||||
#include "global.h"
|
||||
|
||||
bool sim_initialized = false;
|
||||
|
||||
void sim_init() {
|
||||
if (sim_initialized) {
|
||||
return;
|
||||
}
|
||||
physics_world_create();
|
||||
sim_initialized = true;
|
||||
}
|
||||
|
||||
void sim_update() {
|
||||
render_path_raytrace_ready = false;
|
||||
|
||||
if (sim_running) {
|
||||
trait_update();
|
||||
physics_world_update();
|
||||
iron_delay_idle_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
void sim_play() {
|
||||
sim_running = true;
|
||||
}
|
||||
|
||||
void sim_stop() {
|
||||
sim_running = false;
|
||||
trait_stop();
|
||||
}
|
||||
|
||||
void sim_add_body(object_t *o, physics_shape_t shape, f32 mass) {
|
||||
sim_init();
|
||||
physics_body_create(o, shape, mass);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
i32 shape; // -1 = no physics
|
||||
f32 mass;
|
||||
} sim_physics_t;
|
||||
|
||||
static any_imap_t *sim_physics_map = NULL; // object uid -> sim_physics_t
|
||||
|
||||
static sim_physics_t *sim_physics_find(object_t *o) {
|
||||
if (o == NULL || sim_physics_map == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return any_imap_get(sim_physics_map, o->uid);
|
||||
}
|
||||
|
||||
static bool sim_physics_in_stage_of(stage_t *stage, object_t *o) {
|
||||
return stage == NULL || string_array_index_of(stage->objects, o->name) >= 0;
|
||||
}
|
||||
|
||||
static bool sim_physics_in_stage(object_t *o) {
|
||||
return sim_physics_in_stage_of(tab_stages_get_stage(), o);
|
||||
}
|
||||
|
||||
void sim_physics_clear() {
|
||||
sim_physics_map = NULL;
|
||||
}
|
||||
|
||||
void sim_physics_store(object_t *o, i32 shape, f32 mass) {
|
||||
if (o == NULL) {
|
||||
return;
|
||||
}
|
||||
if (sim_physics_map == NULL) {
|
||||
sim_physics_map = any_imap_create();
|
||||
}
|
||||
sim_physics_t *p = any_imap_get(sim_physics_map, o->uid);
|
||||
if (p == NULL) {
|
||||
p = ALLOC_INIT(sim_physics_t, {0});
|
||||
any_imap_set(sim_physics_map, o->uid, p);
|
||||
}
|
||||
p->shape = shape;
|
||||
p->mass = mass;
|
||||
}
|
||||
|
||||
void sim_physics_set(object_t *o, i32 shape, f32 mass) {
|
||||
if (o == NULL) {
|
||||
return;
|
||||
}
|
||||
sim_physics_store(o, shape, mass);
|
||||
if (o->_->body != NULL) {
|
||||
physics_body_remove(o->_->body);
|
||||
}
|
||||
if (shape >= 0 && sim_physics_in_stage(o)) {
|
||||
sim_add_body(o, (physics_shape_t)shape, mass);
|
||||
}
|
||||
}
|
||||
|
||||
void sim_physics_set_mass(object_t *o, f32 mass) {
|
||||
if (o == NULL) {
|
||||
return;
|
||||
}
|
||||
sim_physics_store(o, sim_physics_get_shape(o), mass);
|
||||
if (o->_->body != NULL) {
|
||||
physics_body_set_mass(o->_->body, mass); // Zero mass = static
|
||||
}
|
||||
}
|
||||
|
||||
i32 sim_physics_get_shape(object_t *o) {
|
||||
if (o != NULL && o->_->body != NULL) {
|
||||
return o->_->body->shape;
|
||||
}
|
||||
sim_physics_t *p = sim_physics_find(o);
|
||||
return p != NULL ? p->shape : -1;
|
||||
}
|
||||
|
||||
f32 sim_physics_get_mass(object_t *o) {
|
||||
if (o != NULL && o->_->body != NULL) {
|
||||
return o->_->body->mass;
|
||||
}
|
||||
sim_physics_t *p = sim_physics_find(o);
|
||||
return p != NULL ? p->mass : 0.0;
|
||||
}
|
||||
|
||||
static bool sim_physics_is_shared(i32 shape) {
|
||||
return shape == PHYSICS_SHAPE_MESH || shape == PHYSICS_SHAPE_TERRAIN;
|
||||
}
|
||||
|
||||
void sim_physics_apply_stage(stage_t *stage) {
|
||||
bool shared_cleared = false;
|
||||
|
||||
// Drop the bodies which are no longer in the stage
|
||||
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
object_t *o = g_project->_->paint_objects->buffer[i]->base;
|
||||
sim_physics_t *p = sim_physics_find(o);
|
||||
i32 shape = p != NULL ? p->shape : -1;
|
||||
if (o->_->body == NULL || (shape >= 0 && sim_physics_in_stage_of(stage, o))) {
|
||||
continue;
|
||||
}
|
||||
shared_cleared = shared_cleared || sim_physics_is_shared(o->_->body->shape);
|
||||
physics_body_remove(o->_->body);
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
object_t *o = g_project->_->paint_objects->buffer[i]->base;
|
||||
sim_physics_t *p = sim_physics_find(o);
|
||||
i32 shape = p != NULL ? p->shape : -1;
|
||||
if (shape < 0 || !sim_physics_in_stage_of(stage, o)) {
|
||||
continue;
|
||||
}
|
||||
if (o->_->body != NULL) {
|
||||
if (!shared_cleared || !sim_physics_is_shared(shape)) {
|
||||
continue;
|
||||
}
|
||||
physics_body_remove(o->_->body);
|
||||
}
|
||||
sim_add_body(o, (physics_shape_t)shape, p->mass);
|
||||
}
|
||||
}
|
||||
|
||||
static void sim_shift_object_masks(i32 from) {
|
||||
if (g_project->_->layers != NULL) {
|
||||
for (i32 i = 0; i < g_project->_->layers->length; ++i) {
|
||||
slot_layer_t *l = g_project->_->layers->buffer[i];
|
||||
if (l->object_mask >= from) {
|
||||
++l->object_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (g_context->layer_filter >= from) {
|
||||
++g_context->layer_filter;
|
||||
}
|
||||
}
|
||||
|
||||
mesh_object_t *sim_duplicate_object(mesh_object_t *so) {
|
||||
// Mesh
|
||||
if (so == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mesh_data_t *data = so->data;
|
||||
mesh_object_t *dup = scene_add_mesh_object(data, so->material, so->base->parent);
|
||||
transform_set_matrix(dup->base->transform, so->base->transform->local);
|
||||
|
||||
// Insert below the original
|
||||
i32 index = array_index_of(g_project->_->paint_objects, so);
|
||||
i32 at = index < 0 ? g_project->_->paint_objects->length : index + 1;
|
||||
array_insert((any_array_t *)g_project->_->paint_objects, at, dup);
|
||||
sim_shift_object_masks(at + 1);
|
||||
|
||||
// Ensure unique name
|
||||
dup->base->name = string_copy(_import_mesh_unique_name(so->base->name));
|
||||
tab_stages_add_object(dup->base->name);
|
||||
|
||||
// Material override
|
||||
i32 mat_index = tab_meshes_get_override(so);
|
||||
if (mat_index >= 0) {
|
||||
tab_meshes_set_override_data(dup, mat_index, so->material);
|
||||
g_project->mesh_materials = i32_array_create(0);
|
||||
}
|
||||
|
||||
// Physics
|
||||
i32 shape = sim_physics_get_shape(so->base);
|
||||
if (shape >= 0) {
|
||||
sim_physics_set(dup->base, shape, sim_physics_get_mass(so->base));
|
||||
}
|
||||
|
||||
tab_meshes_sort_hierarchy();
|
||||
tab_timeline_sync();
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
void sim_duplicate() {
|
||||
mesh_object_t *dup = sim_duplicate_object(g_context->paint_object);
|
||||
if (dup != NULL) {
|
||||
g_context->paint_object = dup;
|
||||
ui_header_handle->redraws = 2;
|
||||
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
|
||||
}
|
||||
util_mesh_merge(NULL);
|
||||
g_context->ddirty = 2;
|
||||
}
|
||||
|
||||
void sim_delete() {
|
||||
if (g_project->_->paint_objects->length < 2) {
|
||||
return;
|
||||
}
|
||||
tab_meshes_draw_context_menu_delete(g_context->paint_object);
|
||||
}
|
||||
@@ -430,7 +430,7 @@ void tab_meshes_draw_context_menu_delete(mesh_object_t *o) {
|
||||
o->base->visible = false;
|
||||
g_context->paint_object = tab_meshes_select_after_delete();
|
||||
util_mesh_visibility_changed();
|
||||
sim_physics_apply_stage(stage);
|
||||
util_physics_apply_stage(stage);
|
||||
ui_header_handle->redraws = 2;
|
||||
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
|
||||
return;
|
||||
@@ -456,7 +456,7 @@ static char *f32_to_string2(float f) {
|
||||
}
|
||||
|
||||
void tab_meshes_duplicate_next_frame(void *_) {
|
||||
sim_duplicate();
|
||||
util_mesh_duplicate();
|
||||
}
|
||||
|
||||
void tab_meshes_merge_geometry_next_frame(void *_) {
|
||||
@@ -570,7 +570,7 @@ void tab_meshes_draw_context_menu() {
|
||||
return;
|
||||
}
|
||||
if (ui_menu_button(tr("Duplicate"), "ctrl+d", ICON_DUPLICATE)) {
|
||||
sim_duplicate();
|
||||
util_mesh_duplicate();
|
||||
return;
|
||||
}
|
||||
if (tab_meshes_slot_below(o) != NULL && ui_menu_button(tr("Merge Down"), "", ICON_NONE)) {
|
||||
@@ -677,7 +677,7 @@ void tab_meshes_draw_context_menu() {
|
||||
}
|
||||
|
||||
// Physics
|
||||
i32 shape = sim_physics_get_shape(o->base);
|
||||
i32 shape = util_physics_get_shape(o->base);
|
||||
string_array_t *phys_combo = string_array_create(0);
|
||||
string_array_push(phys_combo, ""); // Empty = no physics
|
||||
string_array_push(phys_combo, tr("Box"));
|
||||
@@ -694,16 +694,16 @@ void tab_meshes_draw_context_menu() {
|
||||
if (phys_changed) {
|
||||
shape = phys - 1;
|
||||
bool dynamic = shape == PHYSICS_SHAPE_BOX || shape == PHYSICS_SHAPE_SPHERE;
|
||||
sim_physics_set(o->base, shape, shape < 0 ? 0.0 : (dynamic ? 1.0 : 0.0));
|
||||
util_physics_set(o->base, shape, shape < 0 ? 0.0 : (dynamic ? 1.0 : 0.0));
|
||||
g_project->mesh_physics_shapes = i32_array_create(0);
|
||||
}
|
||||
|
||||
if (shape >= 0) {
|
||||
f32 mass = sim_physics_get_mass(o->base);
|
||||
f32 mass = util_physics_get_mass(o->base);
|
||||
ui_set_next_id(4);
|
||||
ui_slider(&mass, tr("Mass"), 0.0, 10.0, true, 100, true, UI_ALIGN_LEFT, true);
|
||||
if (ui_item_changed()) {
|
||||
sim_physics_set_mass(o->base, mass);
|
||||
util_physics_set_mass(o->base, mass);
|
||||
g_project->mesh_physics_shapes = i32_array_create(0);
|
||||
ui_menu_keep_open = true;
|
||||
}
|
||||
|
||||
@@ -1606,7 +1606,7 @@ void tab_timeline_stage_edit_box_draw() {
|
||||
o->base->visible = in_stage;
|
||||
tab_stages_set_hidden(s, o->base->name, false);
|
||||
util_mesh_visibility_changed();
|
||||
sim_physics_apply_stage(s);
|
||||
util_physics_apply_stage(s);
|
||||
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1554,3 +1554,74 @@ void util_mesh_subdivide() {
|
||||
plugin_uv_unwrap_button();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _util_mesh_shift_object_masks(i32 from) {
|
||||
if (g_project->_->layers != NULL) {
|
||||
for (i32 i = 0; i < g_project->_->layers->length; ++i) {
|
||||
slot_layer_t *l = g_project->_->layers->buffer[i];
|
||||
if (l->object_mask >= from) {
|
||||
++l->object_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (g_context->layer_filter >= from) {
|
||||
++g_context->layer_filter;
|
||||
}
|
||||
}
|
||||
|
||||
mesh_object_t *util_mesh_duplicate_object(mesh_object_t *so) {
|
||||
// Mesh
|
||||
if (so == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mesh_data_t *data = so->data;
|
||||
mesh_object_t *dup = scene_add_mesh_object(data, so->material, so->base->parent);
|
||||
transform_set_matrix(dup->base->transform, so->base->transform->local);
|
||||
|
||||
// Insert below the original
|
||||
i32 index = array_index_of(g_project->_->paint_objects, so);
|
||||
i32 at = index < 0 ? g_project->_->paint_objects->length : index + 1;
|
||||
array_insert((any_array_t *)g_project->_->paint_objects, at, dup);
|
||||
_util_mesh_shift_object_masks(at + 1);
|
||||
|
||||
// Ensure unique name
|
||||
dup->base->name = string_copy(_import_mesh_unique_name(so->base->name));
|
||||
tab_stages_add_object(dup->base->name);
|
||||
|
||||
// Material override
|
||||
i32 mat_index = tab_meshes_get_override(so);
|
||||
if (mat_index >= 0) {
|
||||
tab_meshes_set_override_data(dup, mat_index, so->material);
|
||||
g_project->mesh_materials = i32_array_create(0);
|
||||
}
|
||||
|
||||
// Physics
|
||||
i32 shape = util_physics_get_shape(so->base);
|
||||
if (shape >= 0) {
|
||||
util_physics_set(dup->base, shape, util_physics_get_mass(so->base));
|
||||
}
|
||||
|
||||
tab_meshes_sort_hierarchy();
|
||||
tab_timeline_sync();
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
void util_mesh_duplicate() {
|
||||
mesh_object_t *dup = util_mesh_duplicate_object(g_context->paint_object);
|
||||
if (dup != NULL) {
|
||||
g_context->paint_object = dup;
|
||||
ui_header_handle->redraws = 2;
|
||||
ui_base_hwnds->buffer[TAB_AREA_SIDEBAR0]->redraws = 2;
|
||||
}
|
||||
util_mesh_merge(NULL);
|
||||
g_context->ddirty = 2;
|
||||
}
|
||||
|
||||
void util_mesh_delete() {
|
||||
if (g_project->_->paint_objects->length < 2) {
|
||||
return;
|
||||
}
|
||||
tab_meshes_draw_context_menu_delete(g_context->paint_object);
|
||||
}
|
||||
|
||||
@@ -12,17 +12,12 @@ void util_particle_init_mesh() {
|
||||
g_context->paint_body = physics_body_create(g_context->merged_object->base, PHYSICS_SHAPE_MESH, 0.0);
|
||||
}
|
||||
|
||||
void util_particle_init_physics() {
|
||||
sim_init();
|
||||
util_particle_init_mesh();
|
||||
}
|
||||
|
||||
void util_particle_update() {
|
||||
if (g_context->tool != TOOL_TYPE_PARTICLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
util_particle_init_physics();
|
||||
util_particle_init_mesh();
|
||||
make_particle_get_bullet_material();
|
||||
physics_world_update();
|
||||
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
#include "../global.h"
|
||||
|
||||
typedef struct {
|
||||
i32 shape; // -1 = no physics
|
||||
f32 mass;
|
||||
} util_physics_t;
|
||||
|
||||
static any_imap_t *util_physics_map = NULL; // object uid -> util_physics_t
|
||||
|
||||
static util_physics_t *util_physics_find(object_t *o) {
|
||||
if (o == NULL || util_physics_map == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return any_imap_get(util_physics_map, o->uid);
|
||||
}
|
||||
|
||||
static bool util_physics_in_stage_of(stage_t *stage, object_t *o) {
|
||||
return stage == NULL || string_array_index_of(stage->objects, o->name) >= 0;
|
||||
}
|
||||
|
||||
static bool util_physics_in_stage(object_t *o) {
|
||||
return util_physics_in_stage_of(tab_stages_get_stage(), o);
|
||||
}
|
||||
|
||||
void util_physics_clear() {
|
||||
util_physics_map = NULL;
|
||||
}
|
||||
|
||||
void util_physics_store(object_t *o, i32 shape, f32 mass) {
|
||||
if (o == NULL) {
|
||||
return;
|
||||
}
|
||||
if (util_physics_map == NULL) {
|
||||
util_physics_map = any_imap_create();
|
||||
}
|
||||
util_physics_t *p = any_imap_get(util_physics_map, o->uid);
|
||||
if (p == NULL) {
|
||||
p = ALLOC_INIT(util_physics_t, {0});
|
||||
any_imap_set(util_physics_map, o->uid, p);
|
||||
}
|
||||
p->shape = shape;
|
||||
p->mass = mass;
|
||||
}
|
||||
|
||||
void util_physics_set(object_t *o, i32 shape, f32 mass) {
|
||||
if (o == NULL) {
|
||||
return;
|
||||
}
|
||||
util_physics_store(o, shape, mass);
|
||||
if (o->_->body != NULL) {
|
||||
physics_body_remove(o->_->body);
|
||||
}
|
||||
if (shape >= 0 && util_physics_in_stage(o)) {
|
||||
physics_body_create(o, (physics_shape_t)shape, mass);
|
||||
}
|
||||
}
|
||||
|
||||
void util_physics_set_mass(object_t *o, f32 mass) {
|
||||
if (o == NULL) {
|
||||
return;
|
||||
}
|
||||
util_physics_store(o, util_physics_get_shape(o), mass);
|
||||
if (o->_->body != NULL) {
|
||||
physics_body_set_mass(o->_->body, mass); // Zero mass = static
|
||||
}
|
||||
}
|
||||
|
||||
i32 util_physics_get_shape(object_t *o) {
|
||||
if (o != NULL && o->_->body != NULL) {
|
||||
return o->_->body->shape;
|
||||
}
|
||||
util_physics_t *p = util_physics_find(o);
|
||||
return p != NULL ? p->shape : -1;
|
||||
}
|
||||
|
||||
f32 util_physics_get_mass(object_t *o) {
|
||||
if (o != NULL && o->_->body != NULL) {
|
||||
return o->_->body->mass;
|
||||
}
|
||||
util_physics_t *p = util_physics_find(o);
|
||||
return p != NULL ? p->mass : 0.0;
|
||||
}
|
||||
|
||||
static bool util_physics_is_shared(i32 shape) {
|
||||
return shape == PHYSICS_SHAPE_MESH || shape == PHYSICS_SHAPE_TERRAIN;
|
||||
}
|
||||
|
||||
void util_physics_apply_stage(stage_t *stage) {
|
||||
bool shared_cleared = false;
|
||||
|
||||
// Drop the bodies which are no longer in the stage
|
||||
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
object_t *o = g_project->_->paint_objects->buffer[i]->base;
|
||||
util_physics_t *p = util_physics_find(o);
|
||||
i32 shape = p != NULL ? p->shape : -1;
|
||||
if (o->_->body == NULL || (shape >= 0 && util_physics_in_stage_of(stage, o))) {
|
||||
continue;
|
||||
}
|
||||
shared_cleared = shared_cleared || util_physics_is_shared(o->_->body->shape);
|
||||
physics_body_remove(o->_->body);
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
object_t *o = g_project->_->paint_objects->buffer[i]->base;
|
||||
util_physics_t *p = util_physics_find(o);
|
||||
i32 shape = p != NULL ? p->shape : -1;
|
||||
if (shape < 0 || !util_physics_in_stage_of(stage, o)) {
|
||||
continue;
|
||||
}
|
||||
if (o->_->body != NULL) {
|
||||
if (!shared_cleared || !util_physics_is_shared(shape)) {
|
||||
continue;
|
||||
}
|
||||
physics_body_remove(o->_->body);
|
||||
}
|
||||
physics_body_create(o, (physics_shape_t)shape, p->mass);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ void tab_stages_apply(stage_t *stage) {
|
||||
}
|
||||
}
|
||||
util_mesh_merge(visibles);
|
||||
sim_physics_apply_stage(stage);
|
||||
util_physics_apply_stage(stage);
|
||||
g_context->ddirty = 2;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user