-Added GLTF scene support (still missing animations and .glb extension)
-Fixed bugs regarding tangent generation in SurfaceTool
This commit is contained in:
parent
b7d98d4d05
commit
5c361485db
10
core/color.h
10
core/color.h
|
@ -140,8 +140,16 @@ struct Color {
|
|||
b < 0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
|
||||
a);
|
||||
}
|
||||
_FORCE_INLINE_ Color to_srgb() const {
|
||||
|
||||
static Color hex(uint32_t p_hex);
|
||||
return Color(
|
||||
r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
|
||||
g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
|
||||
b < 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a);
|
||||
}
|
||||
|
||||
static Color
|
||||
hex(uint32_t p_hex);
|
||||
static Color html(const String &p_color);
|
||||
static bool html_is_valid(const String &p_color);
|
||||
static Color named(const String &p_name);
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
// end
|
||||
#include "editor_settings.h"
|
||||
#include "import/editor_import_collada.h"
|
||||
#include "import/editor_scene_importer_gltf.h"
|
||||
#include "io_plugins/editor_bitmask_import_plugin.h"
|
||||
#include "io_plugins/editor_export_scene.h"
|
||||
#include "io_plugins/editor_font_import_plugin.h"
|
||||
|
@ -5151,6 +5152,10 @@ EditorNode::EditorNode() {
|
|||
Ref<EditorOBJImporter> import_obj;
|
||||
import_obj.instance();
|
||||
import_scene->add_importer(import_obj);
|
||||
|
||||
Ref<EditorSceneImporterGLTF> import_gltf;
|
||||
import_gltf.instance();
|
||||
import_scene->add_importer(import_gltf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,258 @@
|
|||
#ifndef EDITOR_SCENE_IMPORTER_GLTF_H
|
||||
#define EDITOR_SCENE_IMPORTER_GLTF_H
|
||||
|
||||
#include "editor/import/resource_importer_scene.h"
|
||||
#include "scene/3d/skeleton.h"
|
||||
#include "scene/3d/spatial.h"
|
||||
|
||||
class EditorSceneImporterGLTF : public EditorSceneImporter {
|
||||
|
||||
GDCLASS(EditorSceneImporterGLTF, EditorSceneImporter);
|
||||
|
||||
enum {
|
||||
ARRAY_BUFFER = 34962,
|
||||
ELEMENT_ARRAY_BUFFER = 34963,
|
||||
|
||||
TYPE_BYTE = 5120,
|
||||
TYPE_UNSIGNED_BYTE = 5121,
|
||||
TYPE_SHORT = 5122,
|
||||
TYPE_UNSIGNED_SHORT = 5123,
|
||||
TYPE_UNSIGNED_INT = 5125,
|
||||
TYPE_FLOAT = 5126,
|
||||
|
||||
COMPONENT_TYPE_BYTE = 5120,
|
||||
COMPONENT_TYPE_UNSIGNED_BYTE = 5121,
|
||||
COMPONENT_TYPE_SHORT = 5122,
|
||||
COMPONENT_TYPE_UNSIGNED_SHORT = 5123,
|
||||
COMPONENT_TYPE_INT = 5125,
|
||||
COMPONENT_TYPE_FLOAT = 5126,
|
||||
|
||||
};
|
||||
|
||||
String _get_component_type_name(uint32_t p_component);
|
||||
int _get_component_type_size(int component_type);
|
||||
|
||||
enum GLTFType {
|
||||
TYPE_SCALAR,
|
||||
TYPE_VEC2,
|
||||
TYPE_VEC3,
|
||||
TYPE_VEC4,
|
||||
TYPE_MAT2,
|
||||
TYPE_MAT3,
|
||||
TYPE_MAT4,
|
||||
};
|
||||
|
||||
String _get_type_name(GLTFType p_component);
|
||||
|
||||
struct GLTFNode {
|
||||
//matrices need to be transformed to this
|
||||
int parent;
|
||||
|
||||
Transform xform;
|
||||
String name;
|
||||
|
||||
int mesh;
|
||||
int camera;
|
||||
int skin;
|
||||
int skeleton_skin;
|
||||
int child_of_skeleton; // put as children of skeleton
|
||||
Vector<int> skeleton_children; //skeleton put as children of this
|
||||
|
||||
int joint_skin;
|
||||
int joint_bone;
|
||||
|
||||
//keep them for animation
|
||||
Vector3 translation;
|
||||
Quat rotation;
|
||||
Vector3 scale;
|
||||
|
||||
Vector<int> children;
|
||||
|
||||
GLTFNode() {
|
||||
joint_skin = -1;
|
||||
joint_bone = -1;
|
||||
child_of_skeleton = -1;
|
||||
skeleton_skin = -1;
|
||||
mesh = -1;
|
||||
camera = -1;
|
||||
parent = -1;
|
||||
scale = Vector3(1, 1, 1);
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFBufferView {
|
||||
|
||||
int buffer;
|
||||
int byte_offset;
|
||||
int byte_length;
|
||||
int byte_stride;
|
||||
bool indices;
|
||||
//matrices need to be transformed to this
|
||||
|
||||
GLTFBufferView() {
|
||||
buffer = 0;
|
||||
byte_offset = 0;
|
||||
byte_length = 0;
|
||||
byte_stride = 0;
|
||||
indices = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFAccessor {
|
||||
|
||||
int buffer_view;
|
||||
int byte_offset;
|
||||
int component_type;
|
||||
bool normalized;
|
||||
int count;
|
||||
GLTFType type;
|
||||
float min;
|
||||
float max;
|
||||
int sparse_count;
|
||||
int sparse_indices_buffer_view;
|
||||
int sparse_indices_byte_offset;
|
||||
int sparse_indices_component_type;
|
||||
int sparse_values_buffer_view;
|
||||
int sparse_values_byte_offset;
|
||||
|
||||
//matrices need to be transformed to this
|
||||
|
||||
GLTFAccessor() {
|
||||
buffer_view = 0;
|
||||
byte_offset = 0;
|
||||
component_type = 0;
|
||||
normalized = false;
|
||||
count = 0;
|
||||
min = 0;
|
||||
max = 0;
|
||||
sparse_count = 0;
|
||||
sparse_indices_byte_offset = 0;
|
||||
sparse_values_byte_offset = 0;
|
||||
}
|
||||
};
|
||||
struct GLTFTexture {
|
||||
int src_image;
|
||||
};
|
||||
|
||||
struct GLTFSkin {
|
||||
|
||||
String name;
|
||||
struct Bone {
|
||||
Transform inverse_bind;
|
||||
int node;
|
||||
};
|
||||
|
||||
int skeleton;
|
||||
Vector<Bone> bones;
|
||||
|
||||
//matrices need to be transformed to this
|
||||
|
||||
GLTFSkin() {
|
||||
skeleton = -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFMesh {
|
||||
Ref<ArrayMesh> mesh;
|
||||
Vector<float> blend_weights;
|
||||
};
|
||||
|
||||
struct GLTFCamera {
|
||||
|
||||
bool perspective;
|
||||
float fov_size;
|
||||
float zfar;
|
||||
float znear;
|
||||
|
||||
GLTFCamera() {
|
||||
perspective = true;
|
||||
fov_size = 65;
|
||||
zfar = 500;
|
||||
znear = 0.1;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFState {
|
||||
|
||||
Dictionary json;
|
||||
int major_version;
|
||||
int minor_version;
|
||||
Vector<uint8_t> gfb_data;
|
||||
|
||||
Vector<GLTFNode *> nodes;
|
||||
Vector<Vector<uint8_t> > buffers;
|
||||
Vector<GLTFBufferView> buffer_views;
|
||||
Vector<GLTFAccessor> accessors;
|
||||
|
||||
Vector<GLTFMesh> meshes; //meshes are loaded directly, no reason not to.
|
||||
Vector<Ref<Material> > materials;
|
||||
|
||||
String scene_name;
|
||||
Vector<int> root_nodes;
|
||||
|
||||
Vector<GLTFTexture> textures;
|
||||
Vector<Ref<Texture> > images;
|
||||
|
||||
Vector<GLTFSkin> skins;
|
||||
Vector<GLTFCamera> cameras;
|
||||
|
||||
Set<String> unique_names;
|
||||
|
||||
Map<int, Vector<int> > skin_users; //cache skin users
|
||||
|
||||
~GLTFState() {
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
memdelete(nodes[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
String _gen_unique_name(GLTFState &state, const String &p_name);
|
||||
|
||||
Ref<Texture> _get_texture(GLTFState &state, int p_texture);
|
||||
|
||||
Error _parse_json(const String &p_path, GLTFState &state);
|
||||
|
||||
Error _parse_scenes(GLTFState &state);
|
||||
Error _parse_nodes(GLTFState &state);
|
||||
Error _parse_buffers(GLTFState &state, const String &p_base_path);
|
||||
Error _parse_buffer_views(GLTFState &state);
|
||||
GLTFType _get_type_from_str(const String &p_string);
|
||||
Error _parse_accessors(GLTFState &state);
|
||||
Error _decode_buffer_view(GLTFState &state, int p_buffer_view, double *dst, int skip_every, int skip_bytes, int element_size, int count, GLTFType type, int component_count, int component_type, int component_size, bool normalized, int byte_offset, bool for_vertex);
|
||||
Vector<double> _decode_accessor(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
PoolVector<float> _decode_accessor_as_floats(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
PoolVector<int> _decode_accessor_as_ints(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
PoolVector<Vector2> _decode_accessor_as_vec2(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
PoolVector<Vector3> _decode_accessor_as_vec3(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
PoolVector<Color> _decode_accessor_as_color(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
Vector<Transform2D> _decode_accessor_as_xform2d(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
Vector<Basis> _decode_accessor_as_basis(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
Vector<Transform> _decode_accessor_as_xform(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
|
||||
void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, int p_parent_bone);
|
||||
void _generate_node(GLTFState &state, int p_node, Node *p_parent, Node *p_owner, Vector<Skeleton *> &skeletons);
|
||||
Spatial *_generate_scene(GLTFState &state);
|
||||
|
||||
Error _parse_meshes(GLTFState &state);
|
||||
Error _parse_images(GLTFState &state, const String &p_base_path);
|
||||
Error _parse_textures(GLTFState &state);
|
||||
|
||||
Error _parse_materials(GLTFState &state);
|
||||
|
||||
Error _parse_skins(GLTFState &state);
|
||||
|
||||
Error _parse_cameras(GLTFState &state);
|
||||
|
||||
void _assign_scene_names(GLTFState &state);
|
||||
|
||||
public:
|
||||
virtual uint32_t get_import_flags() const;
|
||||
virtual void get_extensions(List<String> *r_extensions) const;
|
||||
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = NULL, Error *r_err = NULL);
|
||||
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags);
|
||||
|
||||
EditorSceneImporterGLTF();
|
||||
};
|
||||
|
||||
#endif // EDITOR_SCENE_IMPORTER_GLTF_H
|
|
@ -244,6 +244,7 @@ def build_glsl_header(filename):
|
|||
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }\n\n")
|
||||
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={p_vec2.x,p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n")
|
||||
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={p_vec3.x,p_vec3.y,p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n")
|
||||
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Plane& p_plane) { _FU GLfloat plane[4]={p_plane.normal.x,p_plane.normal.y,p_plane.normal.z,p_plane.d}; glUniform4fv(get_uniform(p_uniform),1,plane); }\n\n")
|
||||
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU glUniform2f(get_uniform(p_uniform),p_a,p_b); }\n\n")
|
||||
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }\n\n")
|
||||
fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU glUniform4f(get_uniform(p_uniform),p_a,p_b,p_c,p_d); }\n\n")
|
||||
|
|
|
@ -234,6 +234,14 @@ void SpatialMaterial::init_shaders() {
|
|||
|
||||
shader_names->grow = "grow";
|
||||
|
||||
shader_names->metallic_texture_channel = "metallic_texture_channel";
|
||||
shader_names->roughness_texture_channel = "roughness_texture_channel";
|
||||
shader_names->ao_texture_channel = "ao_texture_channel";
|
||||
shader_names->clearcoat_texture_channel = "clearcoat_texture_channel";
|
||||
shader_names->rim_texture_channel = "rim_texture_channel";
|
||||
shader_names->depth_texture_channel = "depth_texture_channel";
|
||||
shader_names->refraction_texture_channel = "refraction_texture_channel";
|
||||
|
||||
shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo";
|
||||
shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic";
|
||||
shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness";
|
||||
|
@ -354,7 +362,9 @@ void SpatialMaterial::_update_shader() {
|
|||
code += "uniform float roughness : hint_range(0,1);\n";
|
||||
code += "uniform float point_size : hint_range(0,128);\n";
|
||||
code += "uniform sampler2D texture_metallic : hint_white;\n";
|
||||
code += "uniform vec4 metallic_texture_channel;\n";
|
||||
code += "uniform sampler2D texture_roughness : hint_white;\n";
|
||||
code += "uniform vec4 roughness_texture_channel;\n";
|
||||
if (billboard_mode == BILLBOARD_PARTICLES) {
|
||||
code += "uniform int particles_anim_h_frames;\n";
|
||||
code += "uniform int particles_anim_v_frames;\n";
|
||||
|
@ -371,6 +381,7 @@ void SpatialMaterial::_update_shader() {
|
|||
if (features[FEATURE_REFRACTION]) {
|
||||
code += "uniform sampler2D texture_refraction;\n";
|
||||
code += "uniform float refraction : hint_range(-16,16);\n";
|
||||
code += "uniform vec4 refraction_texture_channel;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_NORMAL_MAPPING]) {
|
||||
|
@ -393,6 +404,7 @@ void SpatialMaterial::_update_shader() {
|
|||
}
|
||||
if (features[FEATURE_AMBIENT_OCCLUSION]) {
|
||||
code += "uniform sampler2D texture_ambient_occlusion : hint_white;\n";
|
||||
code += "uniform vec4 ao_texture_channel;\n";
|
||||
}
|
||||
|
||||
if (features[FEATURE_DETAIL]) {
|
||||
|
@ -617,15 +629,15 @@ void SpatialMaterial::_update_shader() {
|
|||
|
||||
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tfloat metallic_tex = triplanar_texture(texture_metallic,uv1_power_normal,uv1_world_pos).r;\n";
|
||||
code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_world_pos),metallic_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n";
|
||||
code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n";
|
||||
}
|
||||
code += "\tMETALLIC = metallic_tex * metallic;\n";
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tfloat roughness_tex = triplanar_texture(texture_roughness,uv1_power_normal,uv1_world_pos).r;\n";
|
||||
code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_world_pos),roughness_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n";
|
||||
code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n";
|
||||
}
|
||||
code += "\tROUGHNESS = roughness_tex * roughness;\n";
|
||||
code += "\tSPECULAR = specular;\n";
|
||||
|
@ -656,7 +668,7 @@ void SpatialMaterial::_update_shader() {
|
|||
code += "\tvec3 ref_normal = NORMAL;\n";
|
||||
}
|
||||
|
||||
code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * texture(texture_refraction,base_uv).r * refraction;\n";
|
||||
code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(texture(texture_refraction,base_uv),refraction_texture_channel) * refraction;\n";
|
||||
code += "\tfloat ref_amount = 1.0 - albedo.a * albedo_tex.a;\n";
|
||||
code += "\tEMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n";
|
||||
code += "\tALBEDO *= 1.0 - ref_amount;\n";
|
||||
|
@ -699,15 +711,15 @@ void SpatialMaterial::_update_shader() {
|
|||
if (features[FEATURE_AMBIENT_OCCLUSION]) {
|
||||
if (flags[FLAG_AO_ON_UV2]) {
|
||||
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
|
||||
code += "\tAO = triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_world_pos).r;\n";
|
||||
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_world_pos),ao_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tAO = texture(texture_ambient_occlusion,base_uv2).r;\n";
|
||||
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n";
|
||||
}
|
||||
} else {
|
||||
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
|
||||
code += "\tAO = triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_world_pos).r;\n";
|
||||
code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_world_pos),ao_texture_channel);\n";
|
||||
} else {
|
||||
code += "\tAO = texture(texture_ambient_occlusion,base_uv).r;\n";
|
||||
code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1327,6 +1339,58 @@ float SpatialMaterial::get_grow() const {
|
|||
return grow;
|
||||
}
|
||||
|
||||
static Plane _get_texture_mask(SpatialMaterial::TextureChannel p_channel) {
|
||||
static const Plane masks[5] = {
|
||||
Plane(1, 0, 0, 0),
|
||||
Plane(0, 1, 0, 0),
|
||||
Plane(0, 0, 1, 0),
|
||||
Plane(0, 0, 0, 1),
|
||||
Plane(0.3333333, 0.3333333, 0.3333333, 0),
|
||||
};
|
||||
|
||||
return masks[p_channel];
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_metallic_texture_channel(TextureChannel p_channel) {
|
||||
|
||||
metallic_texture_channel = p_channel;
|
||||
VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic_texture_channel, _get_texture_mask(p_channel));
|
||||
}
|
||||
|
||||
SpatialMaterial::TextureChannel SpatialMaterial::get_metallic_texture_channel() const {
|
||||
return metallic_texture_channel;
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_roughness_texture_channel(TextureChannel p_channel) {
|
||||
|
||||
roughness_texture_channel = p_channel;
|
||||
VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness_texture_channel, _get_texture_mask(p_channel));
|
||||
}
|
||||
|
||||
SpatialMaterial::TextureChannel SpatialMaterial::get_roughness_texture_channel() const {
|
||||
return roughness_texture_channel;
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_ao_texture_channel(TextureChannel p_channel) {
|
||||
|
||||
ao_texture_channel = p_channel;
|
||||
VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel));
|
||||
}
|
||||
|
||||
SpatialMaterial::TextureChannel SpatialMaterial::get_ao_texture_channel() const {
|
||||
return ao_texture_channel;
|
||||
}
|
||||
|
||||
void SpatialMaterial::set_refraction_texture_channel(TextureChannel p_channel) {
|
||||
|
||||
refraction_texture_channel = p_channel;
|
||||
VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
|
||||
}
|
||||
|
||||
SpatialMaterial::TextureChannel SpatialMaterial::get_refraction_texture_channel() const {
|
||||
return refraction_texture_channel;
|
||||
}
|
||||
|
||||
void SpatialMaterial::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
|
||||
|
@ -1455,6 +1519,18 @@ void SpatialMaterial::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &SpatialMaterial::set_grow_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_grow_enabled"), &SpatialMaterial::is_grow_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_metallic_texture_channel", "channel"), &SpatialMaterial::set_metallic_texture_channel);
|
||||
ClassDB::bind_method(D_METHOD("get_metallic_texture_channel"), &SpatialMaterial::get_metallic_texture_channel);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_roughness_texture_channel", "channel"), &SpatialMaterial::set_roughness_texture_channel);
|
||||
ClassDB::bind_method(D_METHOD("get_roughness_texture_channel"), &SpatialMaterial::get_roughness_texture_channel);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ao_texture_channel", "channel"), &SpatialMaterial::set_ao_texture_channel);
|
||||
ClassDB::bind_method(D_METHOD("get_ao_texture_channel"), &SpatialMaterial::get_ao_texture_channel);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &SpatialMaterial::set_refraction_texture_channel);
|
||||
ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &SpatialMaterial::get_refraction_texture_channel);
|
||||
|
||||
ADD_GROUP("Flags", "flags_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
|
||||
|
@ -1490,10 +1566,12 @@ void SpatialMaterial::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_METALLIC);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "metallic_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_metallic_texture_channel", "get_metallic_texture_channel");
|
||||
|
||||
ADD_GROUP("Roughness", "roughness_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ROUGHNESS);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "roughness_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_roughness_texture_channel", "get_roughness_texture_channel");
|
||||
|
||||
ADD_GROUP("Emission", "emission_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_enabled"), "set_feature", "get_feature", FEATURE_EMISSION);
|
||||
|
@ -1527,6 +1605,7 @@ void SpatialMaterial::_bind_methods() {
|
|||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled"), "set_feature", "get_feature", FEATURE_AMBIENT_OCCLUSION);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_on_uv2"), "set_flag", "get_flag", FLAG_AO_ON_UV2);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "ao_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_ao_texture_channel", "get_ao_texture_channel");
|
||||
|
||||
ADD_GROUP("Depth", "depth_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "depth_enabled"), "set_feature", "get_feature", FEATURE_DEPTH_MAPPING);
|
||||
|
@ -1545,6 +1624,7 @@ void SpatialMaterial::_bind_methods() {
|
|||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_REFRACTION);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "refraction_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_refraction_texture_channel", "get_refraction_texture_channel");
|
||||
|
||||
ADD_GROUP("Detail", "detail_");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "detail_enabled"), "set_feature", "get_feature", FEATURE_DETAIL);
|
||||
|
@ -1638,6 +1718,12 @@ void SpatialMaterial::_bind_methods() {
|
|||
BIND_CONSTANT(BILLBOARD_ENABLED);
|
||||
BIND_CONSTANT(BILLBOARD_FIXED_Y);
|
||||
BIND_CONSTANT(BILLBOARD_PARTICLES);
|
||||
|
||||
BIND_CONSTANT(TEXTURE_CHANNEL_RED);
|
||||
BIND_CONSTANT(TEXTURE_CHANNEL_GREEN);
|
||||
BIND_CONSTANT(TEXTURE_CHANNEL_BLUE);
|
||||
BIND_CONSTANT(TEXTURE_CHANNEL_ALPHA);
|
||||
BIND_CONSTANT(TEXTURE_CHANNEL_GRAYSCALE);
|
||||
}
|
||||
|
||||
SpatialMaterial::SpatialMaterial()
|
||||
|
@ -1672,6 +1758,11 @@ SpatialMaterial::SpatialMaterial()
|
|||
set_particles_anim_v_frames(1);
|
||||
set_particles_anim_loop(false);
|
||||
|
||||
set_metallic_texture_channel(TEXTURE_CHANNEL_RED);
|
||||
set_roughness_texture_channel(TEXTURE_CHANNEL_RED);
|
||||
set_ao_texture_channel(TEXTURE_CHANNEL_RED);
|
||||
set_refraction_texture_channel(TEXTURE_CHANNEL_RED);
|
||||
|
||||
grow_enabled = false;
|
||||
set_grow(0.0);
|
||||
|
||||
|
|
|
@ -190,6 +190,14 @@ public:
|
|||
BILLBOARD_PARTICLES,
|
||||
};
|
||||
|
||||
enum TextureChannel {
|
||||
TEXTURE_CHANNEL_RED,
|
||||
TEXTURE_CHANNEL_GREEN,
|
||||
TEXTURE_CHANNEL_BLUE,
|
||||
TEXTURE_CHANNEL_ALPHA,
|
||||
TEXTURE_CHANNEL_GRAYSCALE
|
||||
};
|
||||
|
||||
private:
|
||||
union MaterialKey {
|
||||
|
||||
|
@ -283,6 +291,14 @@ private:
|
|||
StringName uv2_blend_sharpness;
|
||||
StringName grow;
|
||||
|
||||
StringName metallic_texture_channel;
|
||||
StringName roughness_texture_channel;
|
||||
StringName ao_texture_channel;
|
||||
StringName clearcoat_texture_channel;
|
||||
StringName rim_texture_channel;
|
||||
StringName depth_texture_channel;
|
||||
StringName refraction_texture_channel;
|
||||
|
||||
StringName texture_names[TEXTURE_MAX];
|
||||
};
|
||||
|
||||
|
@ -342,6 +358,11 @@ private:
|
|||
DiffuseMode diffuse_mode;
|
||||
BillboardMode billboard_mode;
|
||||
|
||||
TextureChannel metallic_texture_channel;
|
||||
TextureChannel roughness_texture_channel;
|
||||
TextureChannel ao_texture_channel;
|
||||
TextureChannel refraction_texture_channel;
|
||||
|
||||
bool features[FEATURE_MAX];
|
||||
|
||||
Ref<Texture> textures[TEXTURE_MAX];
|
||||
|
@ -478,6 +499,15 @@ public:
|
|||
void set_grow(float p_grow);
|
||||
float get_grow() const;
|
||||
|
||||
void set_metallic_texture_channel(TextureChannel p_channel);
|
||||
TextureChannel get_metallic_texture_channel() const;
|
||||
void set_roughness_texture_channel(TextureChannel p_channel);
|
||||
TextureChannel get_roughness_texture_channel() const;
|
||||
void set_ao_texture_channel(TextureChannel p_channel);
|
||||
TextureChannel get_ao_texture_channel() const;
|
||||
void set_refraction_texture_channel(TextureChannel p_channel);
|
||||
TextureChannel get_refraction_texture_channel() const;
|
||||
|
||||
static void init_shaders();
|
||||
static void finish_shaders();
|
||||
static void flush_changes();
|
||||
|
@ -496,6 +526,7 @@ VARIANT_ENUM_CAST(SpatialMaterial::Flags)
|
|||
VARIANT_ENUM_CAST(SpatialMaterial::DiffuseMode)
|
||||
VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode)
|
||||
VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode)
|
||||
VARIANT_ENUM_CAST(SpatialMaterial::TextureChannel)
|
||||
|
||||
//////////////////////
|
||||
|
||||
|
|
|
@ -224,30 +224,22 @@ void SurfaceTool::add_index(int p_index) {
|
|||
index_array.push_back(p_index);
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
||||
|
||||
Ref<ArrayMesh> mesh;
|
||||
if (p_existing.is_valid())
|
||||
mesh = p_existing;
|
||||
else
|
||||
mesh.instance();
|
||||
Array SurfaceTool::commit_to_arrays() {
|
||||
|
||||
int varr_len = vertex_array.size();
|
||||
|
||||
if (varr_len == 0)
|
||||
return mesh;
|
||||
|
||||
int surface = mesh->get_surface_count();
|
||||
|
||||
Array a;
|
||||
a.resize(Mesh::ARRAY_MAX);
|
||||
|
||||
for (int i = 0; i < Mesh::ARRAY_MAX; i++) {
|
||||
|
||||
switch (format & (1 << i)) {
|
||||
if (!(format & (1 << i)))
|
||||
continue; //not in format
|
||||
|
||||
case Mesh::ARRAY_FORMAT_VERTEX:
|
||||
case Mesh::ARRAY_FORMAT_NORMAL: {
|
||||
switch (i) {
|
||||
|
||||
case Mesh::ARRAY_VERTEX:
|
||||
case Mesh::ARRAY_NORMAL: {
|
||||
|
||||
PoolVector<Vector3> array;
|
||||
array.resize(varr_len);
|
||||
|
@ -273,8 +265,8 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
|
||||
} break;
|
||||
|
||||
case Mesh::ARRAY_FORMAT_TEX_UV:
|
||||
case Mesh::ARRAY_FORMAT_TEX_UV2: {
|
||||
case Mesh::ARRAY_TEX_UV:
|
||||
case Mesh::ARRAY_TEX_UV2: {
|
||||
|
||||
PoolVector<Vector2> array;
|
||||
array.resize(varr_len);
|
||||
|
@ -299,7 +291,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
w = PoolVector<Vector2>::Write();
|
||||
a[i] = array;
|
||||
} break;
|
||||
case Mesh::ARRAY_FORMAT_TANGENT: {
|
||||
case Mesh::ARRAY_TANGENT: {
|
||||
|
||||
PoolVector<float> array;
|
||||
array.resize(varr_len * 4);
|
||||
|
@ -323,7 +315,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
a[i] = array;
|
||||
|
||||
} break;
|
||||
case Mesh::ARRAY_FORMAT_COLOR: {
|
||||
case Mesh::ARRAY_COLOR: {
|
||||
|
||||
PoolVector<Color> array;
|
||||
array.resize(varr_len);
|
||||
|
@ -339,7 +331,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
w = PoolVector<Color>::Write();
|
||||
a[i] = array;
|
||||
} break;
|
||||
case Mesh::ARRAY_FORMAT_BONES: {
|
||||
case Mesh::ARRAY_BONES: {
|
||||
|
||||
PoolVector<int> array;
|
||||
array.resize(varr_len * 4);
|
||||
|
@ -361,7 +353,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
a[i] = array;
|
||||
|
||||
} break;
|
||||
case Mesh::ARRAY_FORMAT_WEIGHTS: {
|
||||
case Mesh::ARRAY_WEIGHTS: {
|
||||
|
||||
PoolVector<float> array;
|
||||
array.resize(varr_len * 4);
|
||||
|
@ -383,7 +375,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
a[i] = array;
|
||||
|
||||
} break;
|
||||
case Mesh::ARRAY_FORMAT_INDEX: {
|
||||
case Mesh::ARRAY_INDEX: {
|
||||
|
||||
ERR_CONTINUE(index_array.size() == 0);
|
||||
|
||||
|
@ -398,6 +390,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
}
|
||||
|
||||
w = PoolVector<int>::Write();
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
|
||||
|
@ -405,6 +398,26 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
|||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
|
||||
|
||||
Ref<ArrayMesh> mesh;
|
||||
if (p_existing.is_valid())
|
||||
mesh = p_existing;
|
||||
else
|
||||
mesh.instance();
|
||||
|
||||
int varr_len = vertex_array.size();
|
||||
|
||||
if (varr_len == 0)
|
||||
return mesh;
|
||||
|
||||
int surface = mesh->get_surface_count();
|
||||
|
||||
Array a = commit_to_arrays();
|
||||
|
||||
mesh->add_surface_from_arrays(primitive, a);
|
||||
if (material.is_valid())
|
||||
mesh->surface_set_material(surface, material);
|
||||
|
@ -459,12 +472,17 @@ void SurfaceTool::deindex() {
|
|||
vertex_array.push_back(varr[E->get()]);
|
||||
}
|
||||
format &= ~Mesh::ARRAY_FORMAT_INDEX;
|
||||
index_array.clear();
|
||||
}
|
||||
|
||||
void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
|
||||
|
||||
Array arr = p_existing->surface_get_arrays(p_surface);
|
||||
ERR_FAIL_COND(arr.size() != VS::ARRAY_MAX);
|
||||
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
|
||||
}
|
||||
|
||||
void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
|
||||
|
||||
PoolVector<Vector3> varr = arr[VS::ARRAY_VERTEX];
|
||||
PoolVector<Vector3> narr = arr[VS::ARRAY_NORMAL];
|
||||
|
@ -536,7 +554,7 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<
|
|||
if (lformat & VS::ARRAY_FORMAT_TANGENT) {
|
||||
Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]);
|
||||
v.tangent = p.normal;
|
||||
v.binormal = p.normal.cross(last_normal).normalized() * p.d;
|
||||
v.binormal = p.normal.cross(v.tangent).normalized() * p.d;
|
||||
}
|
||||
if (lformat & VS::ARRAY_FORMAT_COLOR)
|
||||
v.color = carr[i];
|
||||
|
@ -580,6 +598,13 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<
|
|||
}
|
||||
}
|
||||
|
||||
void SurfaceTool::create_from_triangle_arrays(const Array &p_arrays) {
|
||||
|
||||
clear();
|
||||
primitive = Mesh::PRIMITIVE_TRIANGLES;
|
||||
_create_list_from_arrays(p_arrays, &vertex_array, &index_array, format);
|
||||
}
|
||||
|
||||
void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) {
|
||||
|
||||
clear();
|
||||
|
@ -711,8 +736,9 @@ void SurfaceTool::generate_tangents() {
|
|||
ERR_FAIL_COND(!res);
|
||||
format |= Mesh::ARRAY_FORMAT_TANGENT;
|
||||
|
||||
if (indexed)
|
||||
if (indexed) {
|
||||
index();
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceTool::generate_normals() {
|
||||
|
@ -784,7 +810,6 @@ void SurfaceTool::generate_normals() {
|
|||
vertex_hash.clear();
|
||||
if (E) {
|
||||
smooth = smooth_groups[count];
|
||||
print_line("SMOOTH AT " + itos(count) + ": " + itos(smooth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ private:
|
|||
Vector<float> last_weights;
|
||||
Plane last_tangent;
|
||||
|
||||
void _create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat);
|
||||
void _create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat);
|
||||
|
||||
//mikktspace callbacks
|
||||
|
@ -123,6 +124,8 @@ public:
|
|||
|
||||
List<Vertex> &get_vertex_array() { return vertex_array; }
|
||||
|
||||
void create_from_triangle_arrays(const Array &p_arrays);
|
||||
Array commit_to_arrays();
|
||||
void create_from(const Ref<Mesh> &p_existing, int p_surface);
|
||||
void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform);
|
||||
Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>());
|
||||
|
|
|
@ -11,9 +11,8 @@
|
|||
|
||||
extern "C" {
|
||||
|
||||
uint32_t base64_encode (char* to, char* from, uint32_t len);
|
||||
uint32_t base64_decode (char* to, char* from, uint32_t len);
|
||||
|
||||
uint32_t base64_encode(char *to, char *from, uint32_t len);
|
||||
uint32_t base64_decode(char *to, char *from, uint32_t len);
|
||||
};
|
||||
|
||||
#endif /* BASE64_H */
|
||||
|
|
Loading…
Reference in New Issue