mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-11-21 16:37:20 +01:00
ProceduralTree3DMesh initial setup.
This commit is contained in:
parent
2a936f4954
commit
755a8b0225
@ -9,7 +9,7 @@ def configure(env):
|
||||
|
||||
def get_doc_classes():
|
||||
return [
|
||||
"ProceduralTree3D",
|
||||
"ProceduralTree3DMesh",
|
||||
]
|
||||
|
||||
def get_doc_path():
|
||||
|
@ -1,34 +1,235 @@
|
||||
|
||||
#include "procedural_tree_3d_mesh.h"
|
||||
#include "core/object/object.h"
|
||||
|
||||
ProceduralTree3D::ProceduralTree3D() {
|
||||
}
|
||||
ProceduralTree3D::~ProceduralTree3D() {
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
void ProceduralTree3DMesh::_update() const {
|
||||
Array arr;
|
||||
arr.resize(RS::ARRAY_MAX);
|
||||
|
||||
PoolVector<Vector3> points = arr[RS::ARRAY_VERTEX];
|
||||
|
||||
aabb = AABB();
|
||||
|
||||
int pc = points.size();
|
||||
ERR_FAIL_COND(pc == 0);
|
||||
{
|
||||
PoolVector<Vector3>::Read r = points.read();
|
||||
for (int i = 0; i < pc; i++) {
|
||||
if (i == 0) {
|
||||
aabb.position = r[i];
|
||||
} else {
|
||||
aabb.expand_to(r[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderingServer::get_singleton()->mesh_clear(mesh);
|
||||
|
||||
// in with the new
|
||||
RenderingServer::get_singleton()->mesh_add_surface_from_arrays(mesh, RenderingServer::PRIMITIVE_TRIANGLES, arr);
|
||||
RenderingServer::get_singleton()->mesh_add_surface_from_arrays(mesh, RenderingServer::PRIMITIVE_TRIANGLES, arr);
|
||||
|
||||
RenderingServer::get_singleton()->mesh_surface_set_material(mesh, TREE_SURFACE_TRUNK, _surfaces[TREE_SURFACE_TRUNK].material.is_null() ? RID() : _surfaces[TREE_SURFACE_TRUNK].material->get_rid());
|
||||
RenderingServer::get_singleton()->mesh_surface_set_material(mesh, TREE_SURFACE_TWIG, _surfaces[TREE_SURFACE_TWIG].material.is_null() ? RID() : _surfaces[TREE_SURFACE_TWIG].material->get_rid());
|
||||
|
||||
pending_request = false;
|
||||
|
||||
clear_cache();
|
||||
|
||||
const_cast<ProceduralTree3DMesh *>(this)->emit_changed();
|
||||
}
|
||||
|
||||
void ProceduralTree3D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_PROCESS: {
|
||||
} break;
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
} break;
|
||||
void ProceduralTree3DMesh::_request_update() {
|
||||
if (pending_request) {
|
||||
return;
|
||||
}
|
||||
_update();
|
||||
}
|
||||
|
||||
int ProceduralTree3DMesh::get_surface_count() const {
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
return TREE_SURFACE_COUNT;
|
||||
}
|
||||
|
||||
int ProceduralTree3DMesh::surface_get_array_len(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, TREE_SURFACE_COUNT, -1);
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
|
||||
return RenderingServer::get_singleton()->mesh_surface_get_array_len(mesh, p_idx);
|
||||
}
|
||||
|
||||
int ProceduralTree3DMesh::surface_get_array_index_len(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, TREE_SURFACE_COUNT, -1);
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
|
||||
return RenderingServer::get_singleton()->mesh_surface_get_array_index_len(mesh, p_idx);
|
||||
}
|
||||
|
||||
Array ProceduralTree3DMesh::surface_get_arrays(int p_surface) const {
|
||||
ERR_FAIL_INDEX_V(p_surface, TREE_SURFACE_COUNT, Array());
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
|
||||
return RenderingServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
|
||||
}
|
||||
|
||||
Array ProceduralTree3DMesh::surface_get_blend_shape_arrays(int p_surface) const {
|
||||
ERR_FAIL_INDEX_V(p_surface, TREE_SURFACE_COUNT, Array());
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
|
||||
return Array();
|
||||
}
|
||||
|
||||
uint32_t ProceduralTree3DMesh::surface_get_format(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, TREE_SURFACE_COUNT, 0);
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
|
||||
return RenderingServer::get_singleton()->mesh_surface_get_format(mesh, p_idx);
|
||||
}
|
||||
|
||||
Mesh::PrimitiveType ProceduralTree3DMesh::surface_get_primitive_type(int p_idx) const {
|
||||
return Mesh::PRIMITIVE_TRIANGLES;
|
||||
}
|
||||
|
||||
void ProceduralTree3DMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
|
||||
ERR_FAIL_INDEX(p_idx, TREE_SURFACE_COUNT);
|
||||
|
||||
switch (p_idx) {
|
||||
case TREE_SURFACE_TRUNK:
|
||||
set_trunk_material(p_material);
|
||||
break;
|
||||
case TREE_SURFACE_TWIG:
|
||||
set_twig_material(p_material);
|
||||
break;
|
||||
case TREE_SURFACE_COUNT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProceduralTree3D::_bind_methods() {
|
||||
/*
|
||||
ADD_SIGNAL(MethodInfo("error", PropertyInfo(Variant::DICTIONARY, "error")));
|
||||
Ref<Material> ProceduralTree3DMesh::surface_get_material(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, TREE_SURFACE_COUNT, nullptr);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_client_id"), &ProceduralTree3D::get_client_id);
|
||||
ClassDB::bind_method(D_METHOD("set_client_id", "val"), &ProceduralTree3D::set_client_id);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "client_id"), "set_client_id", "get_client_id");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_tls_method"), &ProceduralTree3D::get_tls_method);
|
||||
ClassDB::bind_method(D_METHOD("set_tls_method", "val"), &ProceduralTree3D::set_tls_method);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "tls_method", PROPERTY_HINT_ENUM, "NONE,STARTTLS,SMTPS"), "set_tls_method", "get_tls_method");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("send_email", "email"), &ProceduralTree3D::send_email);
|
||||
*/
|
||||
return _surfaces[p_idx].material;
|
||||
}
|
||||
|
||||
int ProceduralTree3DMesh::get_blend_shape_count() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
StringName ProceduralTree3DMesh::get_blend_shape_name(int p_index) const {
|
||||
return StringName();
|
||||
}
|
||||
|
||||
void ProceduralTree3DMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
|
||||
}
|
||||
|
||||
AABB ProceduralTree3DMesh::get_aabb() const {
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
|
||||
return aabb;
|
||||
}
|
||||
|
||||
RID ProceduralTree3DMesh::get_rid() const {
|
||||
if (pending_request) {
|
||||
_update();
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
|
||||
void ProceduralTree3DMesh::set_trunk_material(const Ref<Material> &p_material) {
|
||||
_surfaces[TREE_SURFACE_TRUNK].material = p_material;
|
||||
if (!pending_request) {
|
||||
// just apply it, else it'll happen when _update is called.
|
||||
RenderingServer::get_singleton()->mesh_surface_set_material(mesh, TREE_SURFACE_TRUNK, _surfaces[TREE_SURFACE_TRUNK].material.is_null() ? RID() : _surfaces[TREE_SURFACE_TRUNK].material->get_rid());
|
||||
_change_notify();
|
||||
emit_changed();
|
||||
};
|
||||
}
|
||||
|
||||
Ref<Material> ProceduralTree3DMesh::get_trunk_material() const {
|
||||
return _surfaces[TREE_SURFACE_TRUNK].material;
|
||||
}
|
||||
|
||||
|
||||
void ProceduralTree3DMesh::set_twig_material(const Ref<Material> &p_material) {
|
||||
_surfaces[TREE_SURFACE_TWIG].material = p_material;
|
||||
if (!pending_request) {
|
||||
// just apply it, else it'll happen when _update is called.
|
||||
RenderingServer::get_singleton()->mesh_surface_set_material(mesh, TREE_SURFACE_TWIG, _surfaces[TREE_SURFACE_TWIG].material.is_null() ? RID() : _surfaces[TREE_SURFACE_TWIG].material->get_rid());
|
||||
_change_notify();
|
||||
emit_changed();
|
||||
};
|
||||
}
|
||||
|
||||
Ref<Material> ProceduralTree3DMesh::get_twig_material() const {
|
||||
return _surfaces[TREE_SURFACE_TWIG].material;
|
||||
}
|
||||
|
||||
|
||||
Array ProceduralTree3DMesh::get_mesh_arrays() const {
|
||||
Array arr;
|
||||
|
||||
for (int i = 0; i < TREE_SURFACE_COUNT; ++i) {
|
||||
arr.push_back(surface_get_arrays(i));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
void ProceduralTree3DMesh::set_custom_aabb(const AABB &p_custom) {
|
||||
custom_aabb = p_custom;
|
||||
RS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
AABB ProceduralTree3DMesh::get_custom_aabb() const {
|
||||
return custom_aabb;
|
||||
}
|
||||
|
||||
ProceduralTree3DMesh::ProceduralTree3DMesh() {
|
||||
// defaults
|
||||
mesh = RID_PRIME(RenderingServer::get_singleton()->mesh_create());
|
||||
|
||||
// make sure we do an update after we've finished constructing our object
|
||||
pending_request = true;
|
||||
}
|
||||
|
||||
ProceduralTree3DMesh::~ProceduralTree3DMesh() {
|
||||
RenderingServer::get_singleton()->free(mesh);
|
||||
}
|
||||
|
||||
void ProceduralTree3DMesh::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_update"), &ProceduralTree3DMesh::_update);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_trunk_material", "material"), &ProceduralTree3DMesh::set_trunk_material);
|
||||
ClassDB::bind_method(D_METHOD("get_trunk_material"), &ProceduralTree3DMesh::get_trunk_material);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_twig_material", "material"), &ProceduralTree3DMesh::set_twig_material);
|
||||
ClassDB::bind_method(D_METHOD("get_twig_material"), &ProceduralTree3DMesh::get_twig_material);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_mesh_arrays"), &ProceduralTree3DMesh::get_mesh_arrays);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ProceduralTree3DMesh::set_custom_aabb);
|
||||
ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ProceduralTree3DMesh::get_custom_aabb);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trunk_material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_trunk_material", "get_trunk_material");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "twig_material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_twig_material", "get_twig_material");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
|
||||
}
|
||||
|
@ -1,19 +1,68 @@
|
||||
#ifndef PROCEDURAL_TREE_3D
|
||||
#define PROCEDURAL_TREE_3D
|
||||
#ifndef PROCEDURAL_TREE_3D_MESH_H
|
||||
#define PROCEDURAL_TREE_3D_MESH_H
|
||||
|
||||
#include "scene/main/spatial.h"
|
||||
#include "scene/resources/mesh/mesh.h"
|
||||
|
||||
class ProceduralTree3D : public Spatial {
|
||||
GDCLASS(ProceduralTree3D, Spatial);
|
||||
class ProceduralTree3DMesh : public Mesh {
|
||||
GDCLASS(ProceduralTree3DMesh, Mesh);
|
||||
|
||||
public:
|
||||
enum TreeSurfaces {
|
||||
TREE_SURFACE_TRUNK = 0,
|
||||
TREE_SURFACE_TWIG = 1,
|
||||
TREE_SURFACE_COUNT,
|
||||
};
|
||||
|
||||
ProceduralTree3D();
|
||||
~ProceduralTree3D();
|
||||
virtual int get_surface_count() const;
|
||||
virtual int surface_get_array_len(int p_idx) const;
|
||||
virtual int surface_get_array_index_len(int p_idx) const;
|
||||
virtual Array surface_get_arrays(int p_surface) const;
|
||||
virtual Array surface_get_blend_shape_arrays(int p_surface) const;
|
||||
virtual uint32_t surface_get_format(int p_idx) const;
|
||||
virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const;
|
||||
virtual void surface_set_material(int p_idx, const Ref<Material> &p_material);
|
||||
virtual Ref<Material> surface_get_material(int p_idx) const;
|
||||
virtual int get_blend_shape_count() const;
|
||||
virtual StringName get_blend_shape_name(int p_index) const;
|
||||
virtual void set_blend_shape_name(int p_index, const StringName &p_name);
|
||||
virtual AABB get_aabb() const;
|
||||
virtual RID get_rid() const;
|
||||
|
||||
void set_trunk_material(const Ref<Material> &p_material);
|
||||
Ref<Material> get_trunk_material() const;
|
||||
|
||||
void set_twig_material(const Ref<Material> &p_material);
|
||||
Ref<Material> get_twig_material() const;
|
||||
|
||||
Array get_mesh_arrays() const;
|
||||
|
||||
void set_custom_aabb(const AABB &p_custom);
|
||||
AABB get_custom_aabb() const;
|
||||
|
||||
ProceduralTree3DMesh();
|
||||
~ProceduralTree3DMesh();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
void _request_update();
|
||||
|
||||
private:
|
||||
RID mesh;
|
||||
|
||||
struct TreeSurface {
|
||||
Ref<Material> material;
|
||||
};
|
||||
|
||||
TreeSurface _surfaces[TREE_SURFACE_COUNT];
|
||||
|
||||
mutable AABB aabb;
|
||||
AABB custom_aabb;
|
||||
|
||||
mutable bool pending_request;
|
||||
void _update() const;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(ProceduralTree3DMesh::TreeSurfaces);
|
||||
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
void register_procedural_tree_3d_types(ModuleRegistrationLevel p_level) {
|
||||
if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) {
|
||||
ClassDB::register_class<ProceduralTree3D >();
|
||||
ClassDB::register_class<ProceduralTree3DMesh >();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user