mesh_object.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. type mesh_object_t = {
  2. base?: object_t;
  3. data?: mesh_data_t;
  4. material?: material_data_t;
  5. camera_dist?: f32;
  6. frustum_culling?: bool;
  7. skip_context?: string; // Do not draw this context
  8. force_context?: string; // Draw only this context
  9. };
  10. let _mesh_object_last_pipeline: gpu_pipeline_t = null;
  11. function mesh_object_create(data: mesh_data_t, material: material_data_t): mesh_object_t {
  12. let raw: mesh_object_t = {};
  13. raw.frustum_culling = true;
  14. raw.base = object_create(false);
  15. raw.base.ext = raw;
  16. raw.base.ext_type = "mesh_object_t";
  17. raw.material = material;
  18. mesh_object_set_data(raw, data);
  19. array_push(scene_meshes, raw);
  20. return raw;
  21. }
  22. function mesh_object_set_data(raw: mesh_object_t, data: mesh_data_t) {
  23. raw.data = data;
  24. // Scale-up packed (-1,1) mesh coords
  25. raw.base.transform.scale_world = data.scale_pos;
  26. }
  27. function mesh_object_remove(raw: mesh_object_t) {
  28. array_remove(scene_meshes, raw);
  29. object_remove_super(raw.base);
  30. }
  31. function mesh_object_setup_animation(raw: mesh_object_t, oactions: scene_t[] = null) {
  32. /// if arm_anim
  33. object_setup_animation_super(raw.base, oactions);
  34. /// end
  35. }
  36. function mesh_object_cull_material(raw: mesh_object_t, context: string): bool {
  37. // Skip render if material does not contain current context
  38. if (!mesh_object_valid_context(raw, raw.material, context)) {
  39. raw.base.culled = true;
  40. return true;
  41. }
  42. if (raw.skip_context == context) {
  43. raw.base.culled = true;
  44. return true;
  45. }
  46. if (raw.force_context != null && raw.force_context != context) {
  47. raw.base.culled = true;
  48. return true;
  49. }
  50. raw.base.culled = false;
  51. return false;
  52. }
  53. function mesh_object_cull_mesh(raw: mesh_object_t, context: string, camera: camera_object_t): bool {
  54. if (camera.data.frustum_culling && raw.frustum_culling) {
  55. let radius_scale: f32 = 1.0;
  56. let frustum_planes: frustum_plane_t[] = camera.frustum_planes;
  57. if (!camera_object_sphere_in_frustum(frustum_planes, raw.base.transform, radius_scale)) {
  58. raw.base.culled = true;
  59. return true;
  60. }
  61. }
  62. raw.base.culled = false;
  63. return false;
  64. }
  65. function mesh_object_render(raw: mesh_object_t, context: string, bind_params: string[]) {
  66. if (!raw.base.visible) {
  67. return; // Skip render if object is hidden
  68. }
  69. if (mesh_object_cull_mesh(raw, context, scene_camera)) {
  70. return;
  71. }
  72. if (mesh_object_cull_material(raw, context)) {
  73. return;
  74. }
  75. uniforms_pos_unpack = raw.data.scale_pos;
  76. uniforms_tex_unpack = raw.data.scale_tex;
  77. transform_update(raw.base.transform);
  78. let scontext: shader_context_t = null;
  79. let mcontext: material_context_t = null;
  80. let mat: material_data_t = raw.material;
  81. for (let j: i32 = 0; j < mat.contexts.length; ++j) {
  82. if (mat.contexts[j].name == context) {
  83. scontext = shader_data_get_context(mat._.shader, context);
  84. mcontext = mat.contexts[j];
  85. break;
  86. }
  87. }
  88. if (scontext._.pipe != _mesh_object_last_pipeline) {
  89. gpu_set_pipeline(scontext._.pipe);
  90. _mesh_object_last_pipeline = scontext._.pipe;
  91. }
  92. uniforms_set_context_consts(scontext, bind_params);
  93. uniforms_set_obj_consts(scontext, raw.base);
  94. uniforms_set_material_consts(scontext, mcontext);
  95. gpu_set_vertex_buffer(raw.data._.vertex_buffer);
  96. gpu_set_index_buffer(raw.data._.index_buffer);
  97. gpu_draw();
  98. }
  99. function mesh_object_valid_context(raw: mesh_object_t, mat: material_data_t, context: string): bool {
  100. return material_data_get_context(mat, context) != null;
  101. }
  102. function mesh_object_compute_camera_dist(raw: mesh_object_t, cam_x: f32, cam_y: f32, cam_z: f32) {
  103. // Render path mesh sorting
  104. raw.camera_dist =
  105. vec4_fdist(cam_x, cam_y, cam_z, transform_world_x(raw.base.transform), transform_world_y(raw.base.transform), transform_world_z(raw.base.transform));
  106. }