2023-08-14 19:22:04 +02:00
|
|
|
#region vertex format
|
|
|
|
vertex_format_begin();
|
|
|
|
vertex_format_add_position_3d();
|
|
|
|
vertex_format_add_color();
|
|
|
|
global.VF_POS_COL = vertex_format_end();
|
|
|
|
|
|
|
|
vertex_format_begin();
|
|
|
|
vertex_format_add_position_3d();
|
|
|
|
vertex_format_add_normal();
|
|
|
|
vertex_format_add_texcoord();
|
|
|
|
vertex_format_add_color();
|
|
|
|
global.VF_POS_NORM_TEX_COL = vertex_format_end();
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
function __3dObject() constructor {
|
2023-08-22 20:10:09 +02:00
|
|
|
vertex = [];
|
2023-08-23 20:01:09 +02:00
|
|
|
normal_vertex = [];
|
2023-08-22 20:10:09 +02:00
|
|
|
object_counts = 1;
|
2023-08-23 20:01:09 +02:00
|
|
|
VB = noone;
|
|
|
|
|
|
|
|
NVB = noone;
|
|
|
|
normal_draw_size = 0.2;
|
|
|
|
|
2023-08-14 19:22:04 +02:00
|
|
|
VF = global.VF_POS_COL;
|
|
|
|
render_type = pr_trianglelist;
|
|
|
|
|
|
|
|
custom_shader = noone;
|
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
transform = new __transform();
|
|
|
|
size = new __vec3(1);
|
2023-08-14 19:22:04 +02:00
|
|
|
|
2023-08-29 19:26:18 +02:00
|
|
|
materials = [];
|
|
|
|
matrial_index = [];
|
|
|
|
texture_flip = false;
|
2023-08-17 16:56:54 +02:00
|
|
|
|
2023-08-23 20:01:09 +02:00
|
|
|
static checkParameter = function(params = {}, forceUpdate = false) { #region
|
2023-08-22 11:51:45 +02:00
|
|
|
var _keys = struct_get_names(params);
|
|
|
|
var check = false;
|
|
|
|
for( var i = 0, n = array_length(_keys); i < n; i++ ) {
|
|
|
|
var key = _keys[i];
|
|
|
|
if(self[$ key] != params[$ key])
|
|
|
|
check = true;
|
|
|
|
self[$ key] = params[$ key];
|
|
|
|
}
|
|
|
|
|
2023-08-23 20:01:09 +02:00
|
|
|
if(forceUpdate || check) onParameterUpdate();
|
2023-08-22 11:51:45 +02:00
|
|
|
} #endregion
|
|
|
|
|
|
|
|
static onParameterUpdate = function() {}
|
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
static generateNormal = function(_s = normal_draw_size) { #region
|
2023-08-23 20:01:09 +02:00
|
|
|
if(render_type != pr_trianglelist) return;
|
|
|
|
|
|
|
|
NVB = array_create(object_counts);
|
|
|
|
|
|
|
|
for( var i = 0; i < object_counts; i++ ) {
|
|
|
|
NVB[i] = vertex_create_buffer();
|
|
|
|
|
|
|
|
vertex_begin(NVB[i], global.VF_POS_COL);
|
|
|
|
for( var j = 0, n = array_length(vertex[i]); j < n; j++ ) {
|
|
|
|
var _v = vertex[i][j];
|
2023-08-29 14:33:44 +02:00
|
|
|
|
2023-08-23 20:01:09 +02:00
|
|
|
vertex_position_3d(NVB[i], _v.x, _v.y, _v.z);
|
|
|
|
vertex_color(NVB[i], c_red, 1);
|
|
|
|
|
2023-08-29 14:33:44 +02:00
|
|
|
vertex_position_3d(NVB[i], _v.x + _v.nx * _s, _v.y + _v.ny * _s, _v.z + _v.nz * _s);
|
2023-08-23 20:01:09 +02:00
|
|
|
vertex_color(NVB[i], c_red, 1);
|
|
|
|
}
|
|
|
|
vertex_end(NVB[i]);
|
|
|
|
}
|
|
|
|
} #endregion
|
|
|
|
|
2023-09-28 06:31:34 +02:00
|
|
|
static buildVertex = function(_vertex) { #region
|
2023-08-17 16:56:54 +02:00
|
|
|
var _buffer = vertex_create_buffer();
|
2023-08-14 19:22:04 +02:00
|
|
|
vertex_begin(_buffer, VF);
|
|
|
|
for( var i = 0, n = array_length(_vertex); i < n; i++ ) {
|
|
|
|
var v = _vertex[i];
|
|
|
|
|
|
|
|
switch(VF) {
|
2023-08-22 20:10:09 +02:00
|
|
|
case global.VF_POS_COL : vertex_add_vc(_buffer, v); break;
|
|
|
|
case global.VF_POS_NORM_TEX_COL : vertex_add_vntc(_buffer, v); break;
|
2023-08-14 19:22:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
vertex_end(_buffer);
|
2023-09-17 13:23:24 +02:00
|
|
|
//vertex_freeze(_buffer);
|
2023-08-14 19:22:04 +02:00
|
|
|
|
|
|
|
return _buffer;
|
2023-08-22 11:51:45 +02:00
|
|
|
} #endregion
|
2023-08-17 16:56:54 +02:00
|
|
|
|
2023-08-23 20:01:09 +02:00
|
|
|
static build = function(_buffer = VB, _vertex = vertex, counts = object_counts) { #region
|
2023-08-17 16:56:54 +02:00
|
|
|
if(is_array(_buffer)) {
|
|
|
|
for( var i = 0, n = array_length(_buffer); i < n; i++ )
|
|
|
|
vertex_delete_buffer(_buffer[i])
|
|
|
|
} else if(_buffer != noone) vertex_delete_buffer(_buffer);
|
|
|
|
|
|
|
|
if(array_empty(_vertex)) return noone;
|
|
|
|
|
2023-08-23 20:01:09 +02:00
|
|
|
var _res = array_create(counts);
|
|
|
|
for( var i = 0; i < counts; i++ )
|
2023-08-22 20:10:09 +02:00
|
|
|
_res[i] = buildVertex(_vertex[i]);
|
2023-08-17 16:56:54 +02:00
|
|
|
|
|
|
|
return _res;
|
2023-08-16 20:16:31 +02:00
|
|
|
} #endregion
|
2023-08-14 19:22:04 +02:00
|
|
|
|
2023-08-28 12:56:00 +02:00
|
|
|
static preSubmitVertex = function(scene = {}) {}
|
|
|
|
static postSubmitVertex = function(scene = {}) {}
|
2023-08-16 20:16:31 +02:00
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
static getCenter = function() { return new __vec3(transform.position.x, transform.position.y, transform.position.z); }
|
|
|
|
static getBBOX = function() { return new __bbox3D(size.multiplyVec(transform.scale).multiply(-0.5), size.multiplyVec(transform.scale).multiply(0.5)); }
|
2023-08-22 11:51:45 +02:00
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
static submit = function(scene = {}, shader = noone) { submitVertex(scene, shader); }
|
|
|
|
static submitUI = function(scene = {}, shader = noone) { submitVertex(scene, shader); }
|
|
|
|
static submitSel = function(scene = {}, shader = noone) { #region
|
2023-08-28 12:56:00 +02:00
|
|
|
var _s = variable_clone(scene);
|
|
|
|
_s.show_normal = false;
|
|
|
|
submitVertex(_s, sh_d3d_silhouette);
|
2023-08-23 20:01:09 +02:00
|
|
|
} #endregion
|
2023-08-30 16:40:45 +02:00
|
|
|
static submitShader = function(scene = {}, shader = noone) {}
|
2023-09-11 16:08:58 +02:00
|
|
|
static submitShadow = function(scene = {}, object = noone) {}
|
2023-08-14 19:22:04 +02:00
|
|
|
|
2023-08-28 12:56:00 +02:00
|
|
|
static submitVertex = function(scene = {}, shader = noone) { #region
|
|
|
|
var _shader = sh_d3d_default;
|
|
|
|
|
|
|
|
switch(VF) {
|
|
|
|
case global.VF_POS_NORM_TEX_COL: _shader = sh_d3d_default; break;
|
|
|
|
case global.VF_POS_COL: _shader = sh_d3d_wireframe; break;
|
2023-08-14 19:22:04 +02:00
|
|
|
}
|
|
|
|
|
2023-08-28 12:56:00 +02:00
|
|
|
if(custom_shader != noone) _shader = custom_shader;
|
|
|
|
if(shader != noone) _shader = shader;
|
|
|
|
|
|
|
|
shader_set(_shader);
|
|
|
|
|
|
|
|
preSubmitVertex(scene);
|
2023-08-14 19:22:04 +02:00
|
|
|
|
2023-08-24 19:44:12 +02:00
|
|
|
if(VB != noone) { #region
|
2023-08-30 16:40:45 +02:00
|
|
|
transform.submitMatrix();
|
2023-08-22 11:51:45 +02:00
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
matrix_set(matrix_world, matrix_stack_top());
|
2023-08-24 19:44:12 +02:00
|
|
|
} #endregion
|
2023-08-24 11:59:05 +02:00
|
|
|
|
2023-08-24 19:44:12 +02:00
|
|
|
#region ++++ Submit & Material ++++
|
2023-08-29 19:26:18 +02:00
|
|
|
gpu_set_tex_repeat(true);
|
|
|
|
|
2023-08-24 19:44:12 +02:00
|
|
|
for( var i = 0, n = array_length(VB); i < n; i++ ) {
|
2023-08-30 16:40:45 +02:00
|
|
|
var _ind = array_safe_get(matrial_index, i, i);
|
|
|
|
var _mat = array_safe_get(materials, _ind, noone);
|
2023-08-29 19:26:18 +02:00
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
if(_shader == sh_d3d_default) {
|
2023-08-24 19:44:12 +02:00
|
|
|
if(_mat == noone) {
|
|
|
|
shader_set_f("mat_diffuse", 1);
|
|
|
|
shader_set_f("mat_specular", 0);
|
|
|
|
shader_set_f("mat_shine", 1);
|
|
|
|
shader_set_i("mat_metalic", 0);
|
|
|
|
shader_set_f("mat_reflective", 0);
|
|
|
|
} else
|
|
|
|
_mat.submitShader();
|
2023-08-29 19:26:18 +02:00
|
|
|
|
|
|
|
shader_set_i("mat_flip", texture_flip);
|
2023-08-24 19:44:12 +02:00
|
|
|
var _tex = _mat == noone? -1 : _mat.getTexture();
|
|
|
|
vertex_submit(VB[i], render_type, _tex);
|
2023-08-30 16:40:45 +02:00
|
|
|
} else if(_shader == sh_d3d_geometry) {
|
|
|
|
if(_mat == noone)
|
|
|
|
shader_set_i("use_normal", 0);
|
|
|
|
else
|
|
|
|
_mat.submitGeometry();
|
|
|
|
|
|
|
|
vertex_submit(VB[i], render_type, -1);
|
2023-08-28 12:56:00 +02:00
|
|
|
} else
|
2023-08-24 19:44:12 +02:00
|
|
|
vertex_submit(VB[i], render_type, -1);
|
|
|
|
}
|
2023-08-29 19:26:18 +02:00
|
|
|
|
|
|
|
gpu_set_tex_repeat(false);
|
2023-08-24 19:44:12 +02:00
|
|
|
#endregion
|
2023-08-23 20:01:09 +02:00
|
|
|
|
2023-08-28 12:56:00 +02:00
|
|
|
shader_reset();
|
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
if(scene.show_normal) { #region
|
2023-08-29 14:33:44 +02:00
|
|
|
if(NVB == noone) generateNormal();
|
|
|
|
if(NVB != noone) {
|
|
|
|
shader_set(sh_d3d_wireframe);
|
|
|
|
for( var i = 0, n = array_length(NVB); i < n; i++ )
|
|
|
|
vertex_submit(NVB[i], pr_linelist, -1);
|
|
|
|
shader_reset();
|
|
|
|
}
|
2023-08-24 19:44:12 +02:00
|
|
|
} #endregion
|
2023-08-14 19:22:04 +02:00
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
transform.clearMatrix();
|
2023-08-23 20:01:09 +02:00
|
|
|
matrix_set(matrix_world, matrix_build_identity());
|
|
|
|
|
2023-08-28 12:56:00 +02:00
|
|
|
postSubmitVertex(scene);
|
2023-08-14 19:22:04 +02:00
|
|
|
|
2023-08-16 20:16:31 +02:00
|
|
|
} #endregion
|
2023-08-22 11:51:45 +02:00
|
|
|
|
|
|
|
static clone = function() { #region
|
|
|
|
var _obj = variable_clone(self);
|
|
|
|
return _obj;
|
|
|
|
} #endregion
|
|
|
|
|
|
|
|
static destroy = function() { #region
|
|
|
|
if(is_array(VB)) {
|
|
|
|
for( var i = 0, n = array_length(VB); i < n; i++ )
|
|
|
|
vertex_delete_buffer(VB[i]);
|
|
|
|
} else if(VB != noone)
|
|
|
|
vertex_delete_buffer(VB);
|
|
|
|
onDestroy();
|
|
|
|
} #endregion
|
|
|
|
|
|
|
|
static onDestroy = function() { }
|
2023-08-28 12:56:00 +02:00
|
|
|
|
2023-08-30 16:40:45 +02:00
|
|
|
static toString = function() { return $"[D3D Object\n\t{array_length(vertex)} vertex groups\n\tPosition: {transform.position}\n\tRotation: {transform.rotation}\n\tScale: {transform.scale}]" }
|
2023-08-14 19:22:04 +02:00
|
|
|
}
|