Pixel-Composer/scripts/d3d_object/d3d_object.gml

266 lines
7.5 KiB
Text
Raw Normal View History

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();
2024-06-17 06:22:18 +02:00
vertex_format_add_position_3d(); // x y z // 12
vertex_format_add_normal(); // x y z // 12
vertex_format_add_texcoord(); // u v // 8
vertex_format_add_color(); // r g b a // 4
2023-08-14 19:22:04 +02:00
global.VF_POS_NORM_TEX_COL = vertex_format_end();
global.VF_POS_NORM_TEX_COL_size = 36;
2023-08-14 19:22:04 +02:00
#endregion
function __3dObject() constructor {
vertex = [];
2024-06-17 06:22:18 +02:00
VB = [];
normal_vertex = [];
object_counts = 1;
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 = [];
material_index = [];
2023-08-29 19:26:18 +02:00
texture_flip = false;
2023-08-17 16:56:54 +02:00
static checkParameter = function(params = {}, forceUpdate = false) {
var _keys = struct_get_names(params);
2024-10-05 05:23:57 +02:00
if(forceUpdate) {
struct_override(self, params);
onParameterUpdate();
return;
}
var check = false;
for( var i = 0, n = array_length(_keys); i < n; i++ ) {
var key = _keys[i];
2024-06-25 08:44:08 +02:00
if(!isEqual(self[$ key], params[$ key]))
check = true;
self[$ key] = params[$ key];
}
2024-10-05 05:23:57 +02:00
if(check) onParameterUpdate();
}
static onParameterUpdate = function() {}
static generateNormal = function(_s = normal_draw_size) {
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];
vertex_position_3d(NVB[i], _v.x, _v.y, _v.z);
vertex_color(NVB[i], c_red, 1);
vertex_position_3d(NVB[i], _v.x + _v.nx * _s, _v.y + _v.ny * _s, _v.z + _v.nz * _s);
vertex_color(NVB[i], c_red, 1);
}
vertex_end(NVB[i]);
}
}
static buildVertex = function(_vertex) {
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);
2024-06-16 05:27:57 +02:00
switch(VF) {
case global.VF_POS_COL :
for( var i = 0, n = array_length(_vertex); i < n; i++ ) {
var v = _vertex[i];
vertex_position_3d(_buffer, v.x, v.y, v.z);
vertex_color(_buffer, v.color, v.alpha);
}
break;
case global.VF_POS_NORM_TEX_COL :
for( var i = 0, n = array_length(_vertex); i < n; i++ ) {
var v = _vertex[i];
vertex_position_3d(_buffer, v.x, v.y, v.z);
vertex_normal(_buffer, v.nx, v.ny, v.nz);
vertex_texcoord(_buffer, v.u, v.v);
vertex_color(_buffer, v.color, v.alpha);
}
break;
2023-08-14 19:22:04 +02:00
}
vertex_end(_buffer);
return _buffer;
}
2023-08-17 16:56:54 +02:00
static build = function(_buffer = VB, _vertex = vertex, counts = object_counts) {
2023-08-17 16:56:54 +02:00
if(is_array(_buffer)) {
for( var i = 0, n = array_length(_buffer); i < n; i++ )
2023-10-27 13:55:31 +02:00
if(_buffer[i] != noone) vertex_delete_buffer(_buffer[i])
2023-08-17 16:56:54 +02:00
} else if(_buffer != noone) vertex_delete_buffer(_buffer);
if(array_empty(_vertex)) return noone;
var _res = array_create(counts);
for( var i = 0; i < counts; i++ )
_res[i] = buildVertex(_vertex[i]);
2023-08-17 16:56:54 +02:00
return _res;
}
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)); }
2024-05-01 15:35:42 +02:00
#region params
defDrawParam = { wireframe: false };
defDrawParamW = { wireframe: true };
#endregion
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) {
2023-08-28 12:56:00 +02:00
var _s = variable_clone(scene);
_s.show_normal = false;
submitVertex(_s, sh_d3d_silhouette);
}
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
static submitVertex = function(scene = {}, shader = noone, param = defDrawParam) {
2023-08-28 12:56:00 +02:00
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;
2024-10-07 07:50:21 +02:00
if(!is_undefined(shader)) shader_set(_shader);
2023-08-14 19:22:04 +02:00
2024-10-07 07:50:21 +02:00
preSubmitVertex(scene);
transform.submitMatrix();
matrix_set(matrix_world, matrix_stack_top());
2023-08-24 11:59:05 +02:00
2024-10-07 07:50:21 +02:00
gpu_set_tex_repeat(true);
for( var i = 0, n = array_length(VB); i < n; i++ ) {
var _ind = array_safe_get_fast(material_index, i, i);
var _mat = array_safe_get_fast(materials, _ind, noone);
var _useMat = is_instanceof(_mat, __d3dMaterial);
2024-10-07 07:50:21 +02:00
shader_set_i("mat_flip", texture_flip);
var _tex = _useMat? _mat.getTexture() : -1;
if(_shader == sh_d3d_default) {
if(_useMat) {
_mat.submitShader();
} else {
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);
shader_set_f("mat_texScale", [ 1, 1 ] );
}
} else if(_shader == sh_d3d_geometry) {
if(_useMat) _mat.submitGeometry();
else shader_set_i("use_normal", 0);
2024-02-01 08:38:21 +01:00
2023-08-24 19:44:12 +02:00
}
2023-08-29 19:26:18 +02:00
2024-10-07 07:50:21 +02:00
vertex_submit(VB[i], render_type, _tex);
}
2024-10-07 07:50:21 +02:00
gpu_set_tex_repeat(false);
if(!is_undefined(shader)) shader_reset();
2023-08-28 12:56:00 +02:00
if(scene.show_normal) {
if(NVB == noone) generateNormal();
if(NVB != noone) {
shader_set(sh_d3d_wireframe);
2023-11-15 02:35:30 +01:00
shader_set_color("blend", c_white);
for( var i = 0, n = array_length(NVB); i < n; i++ )
vertex_submit(NVB[i], pr_linelist, -1);
shader_reset();
}
}
2023-08-14 19:22:04 +02:00
2023-08-30 16:40:45 +02:00
transform.clearMatrix();
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
}
static clone = function(_vertex = true, cloneBuffer = false) {
2023-10-24 02:09:04 +02:00
var _obj = new __3dObject();
if(_vertex) {
_obj.vertex = array_create(array_length(vertex));
for( var i = 0, n = array_length(vertex); i < n; i++ ) {
_obj.vertex[i] = array_create(array_length(vertex[i]));
2023-10-24 02:09:04 +02:00
for( var j = 0, m = array_length(vertex[i]); j < m; j++ )
_obj.vertex[i][j] = vertex[i][j].clone();
}
2023-10-24 02:09:04 +02:00
}
if(cloneBuffer) {
_obj.VB = array_create(array_length(VB));
for( var i = 0, n = array_length(VB); i < n; i++ ) {
var _vnum = vertex_get_number(VB[i]);
var _buff = buffer_create(1, buffer_grow, 1);
buffer_copy_from_vertex_buffer(VB[i], 0, _vnum - 1, _buff, 0);
_obj.VB[i] = vertex_create_buffer_from_buffer(_buff, VF);
}
} else {
2024-10-10 13:13:21 +02:00
_obj.VB = [];
}
_obj.NVB = NVB;
_obj.VF = VF;
_obj.render_type = render_type;
_obj.custom_shader = custom_shader;
_obj.object_counts = object_counts;
2023-10-24 02:09:04 +02:00
_obj.transform = transform.clone();
_obj.size = size.clone();
_obj.materials = materials;
_obj.material_index = material_index;
2023-10-24 02:09:04 +02:00
_obj.texture_flip = texture_flip;
return _obj;
}
static destroy = function() {
for( var i = 0, n = array_length(VB); i < n; i++ )
vertex_delete_buffer(VB[i]);
VB = [];
onDestroy();
}
static onDestroy = function() { }
2023-08-28 12:56:00 +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
}