Refactored Mesh internals and formats.
-Changed how mesh data is organized, hoping to make it more efficient on Vulkan and GLES. -Removed compression, it now always uses the most efficient format. -Added support for custom arrays (up to 8 custom formats) -Added support for 8 weights in skeleton data. -Added a simple optional versioning system for imported assets, to reimport if binary is newer -Fixes #43979 (I needed to test) WARNING: -NOT backwards compatible with previous 4.x-devel, will most likely never be, but it will force reimport scenes due to version change. -NOT backwards compatible with 3.x scenes, this will be eventually re-added. -Skeletons not working any longer, will fix in next PR.
This commit is contained in:
parent
3beab2646f
commit
70f5972905
|
@ -102,6 +102,7 @@ public:
|
|||
virtual String get_resource_type() const = 0;
|
||||
virtual float get_priority() const { return 1.0; }
|
||||
virtual int get_import_order() const { return 0; }
|
||||
virtual int get_format_version() const { return 0; }
|
||||
|
||||
struct ImportOption {
|
||||
PropertyInfo option;
|
||||
|
|
|
@ -615,6 +615,7 @@ int RenderingDeviceVulkan::get_format_vertex_size(DataFormat p_format) {
|
|||
case DATA_FORMAT_B8G8R8A8_SNORM:
|
||||
case DATA_FORMAT_B8G8R8A8_UINT:
|
||||
case DATA_FORMAT_B8G8R8A8_SINT:
|
||||
case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||
return 4;
|
||||
case DATA_FORMAT_R16_UNORM:
|
||||
case DATA_FORMAT_R16_SNORM:
|
||||
|
@ -3528,7 +3529,7 @@ RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(cons
|
|||
ERR_FAIL_COND_V(used_locations.has(p_vertex_formats[i].location), INVALID_ID);
|
||||
|
||||
ERR_FAIL_COND_V_MSG(get_format_vertex_size(p_vertex_formats[i].format) == 0, INVALID_ID,
|
||||
"Data format for attachment (" + itos(i) + ") is not valid for a vertex array.");
|
||||
"Data format for attachment (" + itos(i) + "), '" + named_formats[p_vertex_formats[i].format] + "', is not valid for a vertex array.");
|
||||
|
||||
vdcache.bindings[i].binding = i;
|
||||
vdcache.bindings[i].stride = p_vertex_formats[i].stride;
|
||||
|
|
|
@ -357,10 +357,12 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
|
|||
|
||||
List<String> to_check;
|
||||
|
||||
String importer_name;
|
||||
String source_file = "";
|
||||
String source_md5 = "";
|
||||
Vector<String> dest_files;
|
||||
String dest_md5 = "";
|
||||
int version = 0;
|
||||
|
||||
while (true) {
|
||||
assign = Variant();
|
||||
|
@ -384,6 +386,10 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
|
|||
for (int i = 0; i < fa.size(); i++) {
|
||||
to_check.push_back(fa[i]);
|
||||
}
|
||||
} else if (assign == "importer_version") {
|
||||
version = value;
|
||||
} else if (assign == "importer") {
|
||||
importer_name = value;
|
||||
} else if (!p_only_imported_files) {
|
||||
if (assign == "source_file") {
|
||||
source_file = value;
|
||||
|
@ -399,6 +405,12 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
|
|||
|
||||
memdelete(f);
|
||||
|
||||
Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
|
||||
|
||||
if (importer->get_format_version() > version) {
|
||||
return true; // version changed, reimport
|
||||
}
|
||||
|
||||
// Read the md5's from a separate file (so the import parameters aren't dependent on the file version
|
||||
String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_path);
|
||||
FileAccess *md5s = FileAccess::open(base_path + ".md5", FileAccess::READ, &err);
|
||||
|
@ -1576,6 +1588,10 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
|
|||
f->store_line("[remap]");
|
||||
f->store_line("");
|
||||
f->store_line("importer=\"" + importer->get_importer_name() + "\"");
|
||||
int version = importer->get_format_version();
|
||||
if (version > 0) {
|
||||
f->store_line("importer_version=" + itos(importer->get_format_version()));
|
||||
}
|
||||
if (importer->get_resource_type() != "") {
|
||||
f->store_line("type=\"" + importer->get_resource_type() + "\"");
|
||||
}
|
||||
|
|
|
@ -844,19 +844,19 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
|
||||
for (int k = 0; k < vertex_array.size(); k++) {
|
||||
if (normal_src) {
|
||||
surftool->add_normal(vertex_array[k].normal);
|
||||
surftool->set_normal(vertex_array[k].normal);
|
||||
if (binormal_src && tangent_src) {
|
||||
surftool->add_tangent(vertex_array[k].tangent);
|
||||
surftool->set_tangent(vertex_array[k].tangent);
|
||||
}
|
||||
}
|
||||
if (uv_src) {
|
||||
surftool->add_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y));
|
||||
surftool->set_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y));
|
||||
}
|
||||
if (uv2_src) {
|
||||
surftool->add_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y));
|
||||
surftool->set_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y));
|
||||
}
|
||||
if (color_src) {
|
||||
surftool->add_color(vertex_array[k].color);
|
||||
surftool->set_color(vertex_array[k].color);
|
||||
}
|
||||
|
||||
if (has_weights) {
|
||||
|
@ -876,8 +876,8 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
}
|
||||
}
|
||||
|
||||
surftool->add_bones(bones);
|
||||
surftool->add_weights(weights);
|
||||
surftool->set_bones(bones);
|
||||
surftool->set_weights(weights);
|
||||
}
|
||||
|
||||
surftool->add_vertex(vertex_array[k].vertex);
|
||||
|
@ -923,7 +923,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
|
|||
mr.push_back(a);
|
||||
}
|
||||
|
||||
p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), p_use_compression ? Mesh::ARRAY_COMPRESS_DEFAULT : 0);
|
||||
p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), 0);
|
||||
|
||||
if (material.is_valid()) {
|
||||
if (p_use_mesh_material) {
|
||||
|
|
|
@ -970,8 +970,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
|
|||
return OK;
|
||||
}
|
||||
|
||||
bool compress_vert_data = state.import_flags & IMPORT_USE_COMPRESSION;
|
||||
uint32_t mesh_flags = compress_vert_data ? Mesh::ARRAY_COMPRESS_DEFAULT : 0;
|
||||
uint32_t mesh_flags = 0;
|
||||
|
||||
Array meshes = state.json["meshes"];
|
||||
for (GLTFMeshIndex i = 0; i < meshes.size(); i++) {
|
||||
|
|
|
@ -210,7 +210,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
|
|||
bool generate_tangents = p_generate_tangents;
|
||||
Vector3 scale_mesh = p_scale_mesh;
|
||||
Vector3 offset_mesh = p_offset_mesh;
|
||||
int mesh_flags = p_optimize ? Mesh::ARRAY_COMPRESS_DEFAULT : 0;
|
||||
int mesh_flags = 0;
|
||||
|
||||
Vector<Vector3> vertices;
|
||||
Vector<Vector3> normals;
|
||||
|
@ -294,7 +294,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
|
|||
norm += normals.size() + 1;
|
||||
}
|
||||
ERR_FAIL_INDEX_V(norm, normals.size(), ERR_FILE_CORRUPT);
|
||||
surf_tool->add_normal(normals[norm]);
|
||||
surf_tool->set_normal(normals[norm]);
|
||||
}
|
||||
|
||||
if (face[idx].size() >= 2 && face[idx][1] != String()) {
|
||||
|
@ -303,7 +303,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
|
|||
uv += uvs.size() + 1;
|
||||
}
|
||||
ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_FILE_CORRUPT);
|
||||
surf_tool->add_uv(uvs[uv]);
|
||||
surf_tool->set_uv(uvs[uv]);
|
||||
}
|
||||
|
||||
int vtx = face[idx][0].to_int() - 1;
|
||||
|
@ -473,6 +473,10 @@ String ResourceImporterOBJ::get_resource_type() const {
|
|||
return "Mesh";
|
||||
}
|
||||
|
||||
int ResourceImporterOBJ::get_format_version() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ResourceImporterOBJ::get_preset_count() const {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
|
||||
virtual String get_save_extension() const override;
|
||||
virtual String get_resource_type() const override;
|
||||
virtual int get_format_version() const override;
|
||||
|
||||
virtual int get_preset_count() const override;
|
||||
virtual String get_preset_name(int p_idx) const override;
|
||||
|
|
|
@ -172,6 +172,10 @@ String ResourceImporterScene::get_resource_type() const {
|
|||
return "PackedScene";
|
||||
}
|
||||
|
||||
int ResourceImporterScene::get_format_version() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool ResourceImporterScene::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
|
||||
if (p_option.begins_with("animation/")) {
|
||||
if (p_option != "animation/import" && !bool(p_options["animation/import"])) {
|
||||
|
|
|
@ -133,6 +133,7 @@ public:
|
|||
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
|
||||
virtual String get_save_extension() const override;
|
||||
virtual String get_resource_type() const override;
|
||||
virtual int get_format_version() const override;
|
||||
|
||||
virtual int get_preset_count() const override;
|
||||
virtual String get_preset_name(int p_idx) const override;
|
||||
|
|
|
@ -1625,13 +1625,13 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
int pointidx = 0;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
bones.write[0] = parent;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(rootcolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(rootcolor);
|
||||
surface_tool->add_vertex(v0 - grests[parent].basis[j].normalized() * dist * 0.05);
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(rootcolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(rootcolor);
|
||||
surface_tool->add_vertex(v0 + grests[parent].basis[j].normalized() * dist * 0.05);
|
||||
|
||||
if (j == closest) {
|
||||
|
@ -1654,24 +1654,24 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
point += axis * dist * 0.1;
|
||||
|
||||
bones.write[0] = parent;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bonecolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(v0);
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bonecolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(point);
|
||||
|
||||
bones.write[0] = parent;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bonecolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(point);
|
||||
bones.write[0] = i;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bonecolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(v1);
|
||||
points[pointidx++] = point;
|
||||
}
|
||||
|
@ -1680,13 +1680,13 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
SWAP(points[1], points[2]);
|
||||
for (int j = 0; j < 4; j++) {
|
||||
bones.write[0] = parent;
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bonecolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(points[j]);
|
||||
surface_tool->add_bones(bones);
|
||||
surface_tool->add_weights(weights);
|
||||
surface_tool->add_color(bonecolor);
|
||||
surface_tool->set_bones(bones);
|
||||
surface_tool->set_weights(weights);
|
||||
surface_tool->set_color(bonecolor);
|
||||
surface_tool->add_vertex(points[(j + 1) % 4]);
|
||||
}
|
||||
|
||||
|
|
|
@ -5345,7 +5345,7 @@ void Node3DEditor::_init_indicators() {
|
|||
Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m));
|
||||
Vector3 normal = ivec * ofs.x + ivec2 * ofs.y;
|
||||
|
||||
surftool->add_normal(basis.xform(normal));
|
||||
surftool->set_normal(basis.xform(normal));
|
||||
surftool->add_vertex(vertex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -712,8 +712,8 @@ void ARKitInterface::_add_or_update_anchor(GodotARAnchor *p_anchor) {
|
|||
int16_t index = planeAnchor.geometry.triangleIndices[j];
|
||||
simd_float3 vrtx = planeAnchor.geometry.vertices[index];
|
||||
simd_float2 textcoord = planeAnchor.geometry.textureCoordinates[index];
|
||||
surftool->add_uv(Vector2(textcoord[0], textcoord[1]));
|
||||
surftool->add_color(Color(0.8, 0.8, 0.8));
|
||||
surftool->set_uv(Vector2(textcoord[0], textcoord[1]));
|
||||
surftool->set_color(Color(0.8, 0.8, 0.8));
|
||||
surftool->add_vertex(Vector3(vrtx[0], vrtx[1], vrtx[2]));
|
||||
}
|
||||
|
||||
|
|
|
@ -827,8 +827,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
|
|||
Ref<ArrayMesh> mesh;
|
||||
mesh.instance();
|
||||
bool has_uvs = false;
|
||||
bool compress_vert_data = state.import_flags & IMPORT_USE_COMPRESSION;
|
||||
uint32_t mesh_flags = compress_vert_data ? Mesh::ARRAY_COMPRESS_DEFAULT : 0;
|
||||
uint32_t mesh_flags = 0;
|
||||
|
||||
Map<String, uint32_t> morph_mesh_string_lookup;
|
||||
|
||||
|
@ -904,33 +903,33 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
|
|||
// Get the texture coordinates if they exist
|
||||
if (ai_mesh->HasTextureCoords(0)) {
|
||||
has_uvs = true;
|
||||
st->add_uv(Vector2(ai_mesh->mTextureCoords[0][j].x, 1.0f - ai_mesh->mTextureCoords[0][j].y));
|
||||
st->set_uv(Vector2(ai_mesh->mTextureCoords[0][j].x, 1.0f - ai_mesh->mTextureCoords[0][j].y));
|
||||
}
|
||||
|
||||
if (ai_mesh->HasTextureCoords(1)) {
|
||||
has_uvs = true;
|
||||
st->add_uv2(Vector2(ai_mesh->mTextureCoords[1][j].x, 1.0f - ai_mesh->mTextureCoords[1][j].y));
|
||||
st->set_uv2(Vector2(ai_mesh->mTextureCoords[1][j].x, 1.0f - ai_mesh->mTextureCoords[1][j].y));
|
||||
}
|
||||
|
||||
// Assign vertex colors
|
||||
if (ai_mesh->HasVertexColors(0)) {
|
||||
Color color = Color(ai_mesh->mColors[0]->r, ai_mesh->mColors[0]->g, ai_mesh->mColors[0]->b,
|
||||
ai_mesh->mColors[0]->a);
|
||||
st->add_color(color);
|
||||
st->set_color(color);
|
||||
}
|
||||
|
||||
// Work out normal calculations? - this needs work it doesn't work properly on huestos
|
||||
if (ai_mesh->mNormals != nullptr) {
|
||||
const aiVector3D normals = ai_mesh->mNormals[j];
|
||||
const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z);
|
||||
st->add_normal(godot_normal);
|
||||
st->set_normal(godot_normal);
|
||||
if (ai_mesh->HasTangentsAndBitangents()) {
|
||||
const aiVector3D tangents = ai_mesh->mTangents[j];
|
||||
const Vector3 godot_tangent = Vector3(tangents.x, tangents.y, tangents.z);
|
||||
const aiVector3D bitangent = ai_mesh->mBitangents[j];
|
||||
const Vector3 godot_bitangent = Vector3(bitangent.x, bitangent.y, bitangent.z);
|
||||
float d = godot_normal.cross(godot_tangent).dot(godot_bitangent) > 0.0f ? 1.0f : -1.0f;
|
||||
st->add_tangent(Plane(tangents.x, tangents.y, tangents.z, d));
|
||||
st->set_tangent(Plane(tangents.x, tangents.y, tangents.z, d));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -948,8 +947,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
|
|||
weights.write[k] = bone_info[k].weight;
|
||||
}
|
||||
|
||||
st->add_bones(bones);
|
||||
st->add_weights(weights);
|
||||
st->set_bones(bones);
|
||||
st->set_weights(weights);
|
||||
}
|
||||
|
||||
// Assign vertex
|
||||
|
|
|
@ -480,7 +480,6 @@ void SoftBody3D::become_mesh_owner() {
|
|||
Dictionary surface_lods = mesh->surface_get_lods(0);
|
||||
uint32_t surface_format = mesh->surface_get_format(0);
|
||||
|
||||
surface_format &= ~(Mesh::ARRAY_COMPRESS_NORMAL);
|
||||
surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE;
|
||||
|
||||
Ref<ArrayMesh> soft_mesh;
|
||||
|
|
|
@ -157,7 +157,7 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
|
|||
|
||||
bool Mesh::surface_is_softbody_friendly(int p_idx) const {
|
||||
const uint32_t surface_format = surface_get_format(p_idx);
|
||||
return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL)));
|
||||
return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
|
||||
}
|
||||
|
||||
Vector<Face3> Mesh::get_faces() const {
|
||||
|
@ -483,37 +483,59 @@ void Mesh::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED);
|
||||
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_VERTEX);
|
||||
BIND_ENUM_CONSTANT(ARRAY_NORMAL);
|
||||
BIND_ENUM_CONSTANT(ARRAY_TANGENT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COLOR);
|
||||
BIND_ENUM_CONSTANT(ARRAY_TEX_UV);
|
||||
BIND_ENUM_CONSTANT(ARRAY_TEX_UV2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM0);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM1);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM3);
|
||||
BIND_ENUM_CONSTANT(ARRAY_BONES);
|
||||
BIND_ENUM_CONSTANT(ARRAY_WEIGHTS);
|
||||
BIND_ENUM_CONSTANT(ARRAY_INDEX);
|
||||
BIND_ENUM_CONSTANT(ARRAY_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_UNORM);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_SNORM);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_HALF);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_HALF);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_R_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGB_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3_SHIFT);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_MASK);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_FLAGS_BASE);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_8_BONE_WEIGHTS);
|
||||
}
|
||||
|
||||
void Mesh::clear_cache() const {
|
||||
|
@ -559,12 +581,50 @@ Vector<Ref<Shape3D>> Mesh::convex_decompose() const {
|
|||
|
||||
Mesh::Mesh() {
|
||||
}
|
||||
|
||||
#if 0
|
||||
static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) {
|
||||
bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE)));
|
||||
bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES);
|
||||
bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2));
|
||||
bool weight_32 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_TEX_UV2 << 2));
|
||||
enum ArrayType {
|
||||
OLD_ARRAY_VERTEX = 0,
|
||||
OLD_ARRAY_NORMAL = 1,
|
||||
OLD_ARRAY_TANGENT = 2,
|
||||
OLD_ARRAY_COLOR = 3,
|
||||
OLD_ARRAY_TEX_UV = 4,
|
||||
OLD_ARRAY_TEX_UV2 = 5,
|
||||
OLD_ARRAY_BONES = 6,
|
||||
OLD_ARRAY_WEIGHTS = 7,
|
||||
OLD_ARRAY_INDEX = 8,
|
||||
OLD_ARRAY_MAX = 9
|
||||
};
|
||||
|
||||
enum ArrayFormat {
|
||||
/* OLD_ARRAY FORMAT FLAGS */
|
||||
OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory
|
||||
OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL,
|
||||
OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT,
|
||||
OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR,
|
||||
OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV,
|
||||
OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2,
|
||||
OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES,
|
||||
OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS,
|
||||
OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX,
|
||||
|
||||
OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1),
|
||||
OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE),
|
||||
OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE),
|
||||
OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE),
|
||||
OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE),
|
||||
OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE),
|
||||
OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE),
|
||||
OLD_ARRAY_COMPRESS_DEFAULT = OLD_ARRAY_COMPRESS_NORMAL | OLD_ARRAY_COMPRESS_TANGENT | OLD_ARRAY_COMPRESS_COLOR | OLD_ARRAY_COMPRESS_TEX_UV | OLD_ARRAY_COMPRESS_TEX_UV2,
|
||||
|
||||
OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1,
|
||||
OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3,
|
||||
};
|
||||
|
||||
bool vertex_16bit = p_format & ((1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE)));
|
||||
bool has_bones = (p_format & OLD_ARRAY_FORMAT_BONES);
|
||||
bool bone_8 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_INDEX << 2));
|
||||
bool weight_32 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_TEX_UV2 << 2));
|
||||
|
||||
print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32));
|
||||
|
||||
|
@ -572,7 +632,7 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui
|
|||
return p_src;
|
||||
}
|
||||
|
||||
bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1));
|
||||
bool vertex_2d = (p_format & (OLD_ARRAY_COMPRESS_INDEX << 1));
|
||||
|
||||
uint32_t src_stride = p_src.size() / p_elements;
|
||||
uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0);
|
||||
|
@ -671,7 +731,7 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String sname = p_name;
|
||||
|
||||
|
@ -727,6 +787,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
|
|||
add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]);
|
||||
|
||||
} else if (d.has("array_data")) {
|
||||
#if 0
|
||||
//print_line("array data (old style");
|
||||
//older format (3.x)
|
||||
Vector<uint8_t> array_data = d["array_data"];
|
||||
|
@ -793,6 +854,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
|
|||
}
|
||||
|
||||
add_surface(format, PrimitiveType(primitive), array_data, vertex_count, array_index_data, index_count, aabb, blend_shapes, bone_aabb);
|
||||
#endif
|
||||
} else {
|
||||
ERR_FAIL_V(false);
|
||||
}
|
||||
|
@ -824,6 +886,12 @@ Array ArrayMesh::_get_surfaces() const {
|
|||
data["primitive"] = surface.primitive;
|
||||
data["vertex_data"] = surface.vertex_data;
|
||||
data["vertex_count"] = surface.vertex_count;
|
||||
if (surface.skin_data.size()) {
|
||||
data["skin_data"] = surface.skin_data;
|
||||
}
|
||||
if (surface.attribute_data.size()) {
|
||||
data["attribute_data"] = surface.attribute_data;
|
||||
}
|
||||
data["aabb"] = surface.aabb;
|
||||
if (surface.index_count) {
|
||||
data["index_data"] = surface.index_data;
|
||||
|
@ -848,9 +916,9 @@ Array ArrayMesh::_get_surfaces() const {
|
|||
data["bone_aabbs"] = bone_aabbs;
|
||||
}
|
||||
|
||||
Array blend_shapes;
|
||||
for (int j = 0; j < surface.blend_shapes.size(); j++) {
|
||||
blend_shapes.push_back(surface.blend_shapes[j]);
|
||||
if (surface.blend_shape_data.size()) {
|
||||
data["blend_shapes"] = surface.blend_shape_data;
|
||||
data["blend_shapes_count"] = surface.blend_shape_count;
|
||||
}
|
||||
|
||||
if (surfaces[i].material.is_valid()) {
|
||||
|
@ -896,6 +964,12 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
|
|||
surface.primitive = RS::PrimitiveType(int(d["primitive"]));
|
||||
surface.vertex_data = d["vertex_data"];
|
||||
surface.vertex_count = d["vertex_count"];
|
||||
if (d.has("attribute_data")) {
|
||||
surface.attribute_data = d["attribute_data"];
|
||||
}
|
||||
if (d.has("skin_data")) {
|
||||
surface.skin_data = d["skin_data"];
|
||||
}
|
||||
surface.aabb = d["aabb"];
|
||||
|
||||
if (d.has("index_data")) {
|
||||
|
@ -922,11 +996,9 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
|
|||
}
|
||||
}
|
||||
|
||||
if (d.has("blend_shapes")) {
|
||||
Array blend_shapes;
|
||||
for (int j = 0; j < blend_shapes.size(); j++) {
|
||||
surface.blend_shapes.push_back(blend_shapes[j]);
|
||||
}
|
||||
if (d.has("blend_shapes") && d.has("blend_shape_count")) {
|
||||
surface.blend_shape_data = d["blend_shapes"];
|
||||
surface.blend_shape_count = d["blend_shape_count"];
|
||||
}
|
||||
|
||||
Ref<Material> material;
|
||||
|
@ -982,7 +1054,7 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
|
|||
s.aabb = surface_data[i].aabb;
|
||||
if (i == 0) {
|
||||
aabb = s.aabb;
|
||||
blend_shapes.resize(surface_data[i].blend_shapes.size());
|
||||
blend_shapes.resize(surface_data[i].blend_shape_count);
|
||||
} else {
|
||||
aabb.merge_with(s.aabb);
|
||||
}
|
||||
|
@ -1070,7 +1142,7 @@ void ArrayMesh::_recompute_aabb() {
|
|||
#ifndef _MSC_VER
|
||||
#warning need to add binding to add_surface using future MeshSurfaceData object
|
||||
#endif
|
||||
void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<RS::SurfaceData::LOD> &p_lods) {
|
||||
void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data, uint32_t p_blend_shape_count, const Vector<AABB> &p_bone_aabbs, const Vector<RS::SurfaceData::LOD> &p_lods) {
|
||||
_create_if_empty();
|
||||
|
||||
Surface s;
|
||||
|
@ -1090,10 +1162,13 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const
|
|||
sd.aabb = p_aabb;
|
||||
sd.vertex_count = p_vertex_count;
|
||||
sd.vertex_data = p_array;
|
||||
sd.attribute_data = p_attribute_array;
|
||||
sd.skin_data = p_skin_array;
|
||||
sd.index_count = p_index_count;
|
||||
sd.index_data = p_index_array;
|
||||
sd.blend_shapes = p_blend_shapes;
|
||||
sd.bone_aabbs = p_bone_aabb;
|
||||
sd.blend_shape_data = p_blend_shape_data;
|
||||
sd.blend_shape_count = p_blend_shape_count;
|
||||
sd.bone_aabbs = p_bone_aabbs;
|
||||
sd.lods = p_lods;
|
||||
|
||||
RenderingServer::get_singleton()->mesh_add_surface(mesh, sd);
|
||||
|
@ -1119,7 +1194,7 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &
|
|||
print_line("index count: " + itos(surface.index_count));
|
||||
print_line("primitive: " + itos(surface.primitive));
|
||||
*/
|
||||
add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shapes, surface.bone_aabbs, surface.lods);
|
||||
add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.attribute_data, surface.skin_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shape_data, surface.blend_shape_count, surface.bone_aabbs, surface.lods);
|
||||
}
|
||||
|
||||
Array ArrayMesh::surface_get_arrays(int p_surface) const {
|
||||
|
@ -1452,29 +1527,29 @@ Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cach
|
|||
SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second];
|
||||
|
||||
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) {
|
||||
surfaces_tools.write[surface]->add_color(v.color);
|
||||
surfaces_tools.write[surface]->set_color(v.color);
|
||||
}
|
||||
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
|
||||
surfaces_tools.write[surface]->add_uv(v.uv);
|
||||
surfaces_tools.write[surface]->set_uv(v.uv);
|
||||
}
|
||||
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
|
||||
surfaces_tools.write[surface]->add_normal(v.normal);
|
||||
surfaces_tools.write[surface]->set_normal(v.normal);
|
||||
}
|
||||
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
|
||||
Plane t;
|
||||
t.normal = v.tangent;
|
||||
t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
|
||||
surfaces_tools.write[surface]->add_tangent(t);
|
||||
surfaces_tools.write[surface]->set_tangent(t);
|
||||
}
|
||||
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) {
|
||||
surfaces_tools.write[surface]->add_bones(v.bones);
|
||||
surfaces_tools.write[surface]->set_bones(v.bones);
|
||||
}
|
||||
if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
|
||||
surfaces_tools.write[surface]->add_weights(v.weights);
|
||||
surfaces_tools.write[surface]->set_weights(v.weights);
|
||||
}
|
||||
|
||||
Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
|
||||
surfaces_tools.write[surface]->add_uv2(uv2);
|
||||
surfaces_tools.write[surface]->set_uv2(uv2);
|
||||
|
||||
surfaces_tools.write[surface]->add_vertex(v.vertex);
|
||||
}
|
||||
|
@ -1507,7 +1582,7 @@ void ArrayMesh::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
|
||||
ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces);
|
||||
ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region);
|
||||
ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len);
|
||||
|
@ -1546,20 +1621,53 @@ void ArrayMesh::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(ARRAY_COLOR);
|
||||
BIND_ENUM_CONSTANT(ARRAY_TEX_UV);
|
||||
BIND_ENUM_CONSTANT(ARRAY_TEX_UV2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM0);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM1);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM3);
|
||||
BIND_ENUM_CONSTANT(ARRAY_BONES);
|
||||
BIND_ENUM_CONSTANT(ARRAY_WEIGHTS);
|
||||
BIND_ENUM_CONSTANT(ARRAY_INDEX);
|
||||
BIND_ENUM_CONSTANT(ARRAY_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_UNORM);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_SNORM);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_HALF);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_HALF);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_R_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGB_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_FLOAT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_CUSTOM_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3_SHIFT);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_MASK);
|
||||
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_FLAGS_BASE);
|
||||
|
||||
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE);
|
||||
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_8_BONE_WEIGHTS);
|
||||
}
|
||||
|
||||
void ArrayMesh::reload_from_file() {
|
||||
|
|
|
@ -61,6 +61,10 @@ public:
|
|||
ARRAY_COLOR = RenderingServer::ARRAY_COLOR,
|
||||
ARRAY_TEX_UV = RenderingServer::ARRAY_TEX_UV,
|
||||
ARRAY_TEX_UV2 = RenderingServer::ARRAY_TEX_UV2,
|
||||
ARRAY_CUSTOM0 = RenderingServer::ARRAY_CUSTOM0,
|
||||
ARRAY_CUSTOM1 = RenderingServer::ARRAY_CUSTOM1,
|
||||
ARRAY_CUSTOM2 = RenderingServer::ARRAY_CUSTOM2,
|
||||
ARRAY_CUSTOM3 = RenderingServer::ARRAY_CUSTOM3,
|
||||
ARRAY_BONES = RenderingServer::ARRAY_BONES,
|
||||
ARRAY_WEIGHTS = RenderingServer::ARRAY_WEIGHTS,
|
||||
ARRAY_INDEX = RenderingServer::ARRAY_INDEX,
|
||||
|
@ -68,30 +72,47 @@ public:
|
|||
|
||||
};
|
||||
|
||||
enum ArrayCustomFormat {
|
||||
ARRAY_CUSTOM_RGBA8_UNORM,
|
||||
ARRAY_CUSTOM_RGBA8_SNORM,
|
||||
ARRAY_CUSTOM_RG_HALF,
|
||||
ARRAY_CUSTOM_RGBA_HALF,
|
||||
ARRAY_CUSTOM_R_FLOAT,
|
||||
ARRAY_CUSTOM_RG_FLOAT,
|
||||
ARRAY_CUSTOM_RGB_FLOAT,
|
||||
ARRAY_CUSTOM_RGBA_FLOAT,
|
||||
ARRAY_CUSTOM_MAX
|
||||
};
|
||||
|
||||
enum ArrayFormat {
|
||||
/* ARRAY FORMAT FLAGS */
|
||||
ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory
|
||||
ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL,
|
||||
ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT,
|
||||
ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR,
|
||||
ARRAY_FORMAT_TEX_UV = 1 << ARRAY_TEX_UV,
|
||||
ARRAY_FORMAT_TEX_UV2 = 1 << ARRAY_TEX_UV2,
|
||||
ARRAY_FORMAT_BONES = 1 << ARRAY_BONES,
|
||||
ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS,
|
||||
ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX,
|
||||
ARRAY_FORMAT_VERTEX = RS::ARRAY_FORMAT_VERTEX,
|
||||
ARRAY_FORMAT_NORMAL = RS::ARRAY_FORMAT_NORMAL,
|
||||
ARRAY_FORMAT_TANGENT = RS::ARRAY_FORMAT_TANGENT,
|
||||
ARRAY_FORMAT_COLOR = RS::ARRAY_FORMAT_COLOR,
|
||||
ARRAY_FORMAT_TEX_UV = RS::ARRAY_FORMAT_TEX_UV,
|
||||
ARRAY_FORMAT_TEX_UV2 = RS::ARRAY_FORMAT_TEX_UV2,
|
||||
ARRAY_FORMAT_CUSTOM0 = RS::ARRAY_FORMAT_CUSTOM0,
|
||||
ARRAY_FORMAT_CUSTOM1 = RS::ARRAY_FORMAT_CUSTOM1,
|
||||
ARRAY_FORMAT_CUSTOM2 = RS::ARRAY_FORMAT_CUSTOM2,
|
||||
ARRAY_FORMAT_CUSTOM3 = RS::ARRAY_FORMAT_CUSTOM3,
|
||||
ARRAY_FORMAT_BONES = RS::ARRAY_FORMAT_BONES,
|
||||
ARRAY_FORMAT_WEIGHTS = RS::ARRAY_FORMAT_WEIGHTS,
|
||||
ARRAY_FORMAT_INDEX = RS::ARRAY_FORMAT_INDEX,
|
||||
|
||||
ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1),
|
||||
ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_FORMAT_BLEND_SHAPE_MASK = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK,
|
||||
|
||||
ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1,
|
||||
ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3,
|
||||
ARRAY_FORMAT_CUSTOM_BASE = RS::ARRAY_FORMAT_CUSTOM_BASE,
|
||||
ARRAY_FORMAT_CUSTOM0_SHIFT = RS::ARRAY_FORMAT_CUSTOM0_SHIFT,
|
||||
ARRAY_FORMAT_CUSTOM1_SHIFT = RS::ARRAY_FORMAT_CUSTOM1_SHIFT,
|
||||
ARRAY_FORMAT_CUSTOM2_SHIFT = RS::ARRAY_FORMAT_CUSTOM2_SHIFT,
|
||||
ARRAY_FORMAT_CUSTOM3_SHIFT = RS::ARRAY_FORMAT_CUSTOM3_SHIFT,
|
||||
|
||||
ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2
|
||||
ARRAY_FORMAT_CUSTOM_MASK = RS::ARRAY_FORMAT_CUSTOM_MASK,
|
||||
ARRAY_COMPRESS_FLAGS_BASE = RS::ARRAY_COMPRESS_FLAGS_BASE,
|
||||
|
||||
ARRAY_FLAG_USE_2D_VERTICES = RS::ARRAY_FLAG_USE_2D_VERTICES,
|
||||
ARRAY_FLAG_USE_DYNAMIC_UPDATE = RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE,
|
||||
ARRAY_FLAG_USE_8_BONE_WEIGHTS = RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS,
|
||||
|
||||
};
|
||||
|
||||
|
@ -187,9 +208,9 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT);
|
||||
void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0);
|
||||
|
||||
void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes = Vector<Vector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>());
|
||||
void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data = Vector<uint8_t>(), uint32_t p_blend_shape_count = 0, const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>());
|
||||
|
||||
Array surface_get_arrays(int p_surface) const override;
|
||||
Array surface_get_blend_shape_arrays(int p_surface) const override;
|
||||
|
@ -244,6 +265,7 @@ public:
|
|||
|
||||
VARIANT_ENUM_CAST(Mesh::ArrayType);
|
||||
VARIANT_ENUM_CAST(Mesh::ArrayFormat);
|
||||
VARIANT_ENUM_CAST(Mesh::ArrayCustomFormat);
|
||||
VARIANT_ENUM_CAST(Mesh::PrimitiveType);
|
||||
VARIANT_ENUM_CAST(Mesh::BlendShapeMode);
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const {
|
|||
uint32_t PrimitiveMesh::surface_get_format(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, 1, 0);
|
||||
|
||||
return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX | RS::ARRAY_COMPRESS_DEFAULT;
|
||||
return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX;
|
||||
}
|
||||
|
||||
Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const {
|
||||
|
|
|
@ -74,6 +74,12 @@ bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const {
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_CUSTOM_MAX; i++) {
|
||||
if (custom[i] != p_vertex.custom[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -87,6 +93,7 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
|
|||
h = hash_djb2_buffer((const uint8_t *)&p_vtx.color, sizeof(real_t) * 4, h);
|
||||
h = hash_djb2_buffer((const uint8_t *)p_vtx.bones.ptr(), p_vtx.bones.size() * sizeof(int), h);
|
||||
h = hash_djb2_buffer((const uint8_t *)p_vtx.weights.ptr(), p_vtx.weights.size() * sizeof(float), h);
|
||||
h = hash_djb2_buffer((const uint8_t *)&p_vtx.custom[0], sizeof(Color) * RS::ARRAY_CUSTOM_COUNT, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
|
@ -111,8 +118,11 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
|
|||
vtx.bones = last_bones;
|
||||
vtx.tangent = last_tangent.normal;
|
||||
vtx.binormal = last_normal.cross(last_tangent.normal).normalized() * last_tangent.d;
|
||||
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
|
||||
vtx.custom[i] = last_custom[i];
|
||||
}
|
||||
|
||||
const int expected_vertices = 4;
|
||||
const int expected_vertices = skin_weights == SKIN_8_WEIGHTS ? 8 : 4;
|
||||
|
||||
if ((format & Mesh::ARRAY_FORMAT_WEIGHTS || format & Mesh::ARRAY_FORMAT_BONES) && (vtx.weights.size() != expected_vertices || vtx.bones.size() != expected_vertices)) {
|
||||
//ensure vertices are the expected amount
|
||||
|
@ -163,7 +173,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
|
|||
format |= Mesh::ARRAY_FORMAT_VERTEX;
|
||||
}
|
||||
|
||||
void SurfaceTool::add_color(Color p_color) {
|
||||
void SurfaceTool::set_color(Color p_color) {
|
||||
ERR_FAIL_COND(!begun);
|
||||
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_COLOR));
|
||||
|
@ -172,7 +182,7 @@ void SurfaceTool::add_color(Color p_color) {
|
|||
last_color = p_color;
|
||||
}
|
||||
|
||||
void SurfaceTool::add_normal(const Vector3 &p_normal) {
|
||||
void SurfaceTool::set_normal(const Vector3 &p_normal) {
|
||||
ERR_FAIL_COND(!begun);
|
||||
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_NORMAL));
|
||||
|
@ -181,7 +191,7 @@ void SurfaceTool::add_normal(const Vector3 &p_normal) {
|
|||
last_normal = p_normal;
|
||||
}
|
||||
|
||||
void SurfaceTool::add_tangent(const Plane &p_tangent) {
|
||||
void SurfaceTool::set_tangent(const Plane &p_tangent) {
|
||||
ERR_FAIL_COND(!begun);
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TANGENT));
|
||||
|
||||
|
@ -189,7 +199,7 @@ void SurfaceTool::add_tangent(const Plane &p_tangent) {
|
|||
last_tangent = p_tangent;
|
||||
}
|
||||
|
||||
void SurfaceTool::add_uv(const Vector2 &p_uv) {
|
||||
void SurfaceTool::set_uv(const Vector2 &p_uv) {
|
||||
ERR_FAIL_COND(!begun);
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV));
|
||||
|
||||
|
@ -197,7 +207,7 @@ void SurfaceTool::add_uv(const Vector2 &p_uv) {
|
|||
last_uv = p_uv;
|
||||
}
|
||||
|
||||
void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
|
||||
void SurfaceTool::set_uv2(const Vector2 &p_uv2) {
|
||||
ERR_FAIL_COND(!begun);
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV2));
|
||||
|
||||
|
@ -205,19 +215,40 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
|
|||
last_uv2 = p_uv2;
|
||||
}
|
||||
|
||||
void SurfaceTool::add_bones(const Vector<int> &p_bones) {
|
||||
void SurfaceTool::set_custom(int p_index, const Color &p_custom) {
|
||||
ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT);
|
||||
ERR_FAIL_COND(!begun);
|
||||
ERR_FAIL_COND(last_custom_format[p_index] == CUSTOM_MAX);
|
||||
static const uint32_t mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
|
||||
static const uint32_t shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
ERR_FAIL_COND(!first && !(format & mask[p_index]));
|
||||
|
||||
if (first) {
|
||||
format |= mask[p_index];
|
||||
format |= last_custom_format[p_index] << shift[p_index];
|
||||
}
|
||||
last_custom[p_index] = p_custom;
|
||||
}
|
||||
|
||||
void SurfaceTool::set_bones(const Vector<int> &p_bones) {
|
||||
ERR_FAIL_COND(!begun);
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES));
|
||||
|
||||
format |= Mesh::ARRAY_FORMAT_BONES;
|
||||
if (skin_weights == SKIN_8_WEIGHTS) {
|
||||
format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
|
||||
}
|
||||
last_bones = p_bones;
|
||||
}
|
||||
|
||||
void SurfaceTool::add_weights(const Vector<float> &p_weights) {
|
||||
void SurfaceTool::set_weights(const Vector<float> &p_weights) {
|
||||
ERR_FAIL_COND(!begun);
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS));
|
||||
|
||||
format |= Mesh::ARRAY_FORMAT_WEIGHTS;
|
||||
if (skin_weights == SKIN_8_WEIGHTS) {
|
||||
format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
|
||||
}
|
||||
last_weights = p_weights;
|
||||
}
|
||||
|
||||
|
@ -238,15 +269,15 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect
|
|||
#define ADD_POINT(n) \
|
||||
{ \
|
||||
if (p_colors.size() > n) \
|
||||
add_color(p_colors[n]); \
|
||||
set_color(p_colors[n]); \
|
||||
if (p_uvs.size() > n) \
|
||||
add_uv(p_uvs[n]); \
|
||||
set_uv(p_uvs[n]); \
|
||||
if (p_uv2s.size() > n) \
|
||||
add_uv2(p_uv2s[n]); \
|
||||
set_uv2(p_uv2s[n]); \
|
||||
if (p_normals.size() > n) \
|
||||
add_normal(p_normals[n]); \
|
||||
set_normal(p_normals[n]); \
|
||||
if (p_tangents.size() > n) \
|
||||
add_tangent(p_tangents[n]); \
|
||||
set_tangent(p_tangents[n]); \
|
||||
add_vertex(p_vertices[n]); \
|
||||
}
|
||||
|
||||
|
@ -358,18 +389,157 @@ Array SurfaceTool::commit_to_arrays() {
|
|||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case Mesh::ARRAY_BONES: {
|
||||
Vector<int> array;
|
||||
case Mesh::ARRAY_CUSTOM0:
|
||||
case Mesh::ARRAY_CUSTOM1:
|
||||
case Mesh::ARRAY_CUSTOM2:
|
||||
case Mesh::ARRAY_CUSTOM3: {
|
||||
int fmt = i - Mesh::ARRAY_CUSTOM0;
|
||||
switch (last_custom_format[fmt]) {
|
||||
case CUSTOM_RGBA8_UNORM: {
|
||||
Vector<uint8_t> array;
|
||||
array.resize(varr_len * 4);
|
||||
uint8_t *w = array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx * 4 + 0] = CLAMP(int32_t(c.r * 255.0), 0, 255);
|
||||
w[idx * 4 + 1] = CLAMP(int32_t(c.g * 255.0), 0, 255);
|
||||
w[idx * 4 + 2] = CLAMP(int32_t(c.b * 255.0), 0, 255);
|
||||
w[idx * 4 + 3] = CLAMP(int32_t(c.a * 255.0), 0, 255);
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case CUSTOM_RGBA8_SNORM: {
|
||||
Vector<uint8_t> array;
|
||||
array.resize(varr_len * 4);
|
||||
uint8_t *w = array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx * 4 + 0] = uint8_t(int8_t(CLAMP(int32_t(c.r * 127.0), -128, 127)));
|
||||
w[idx * 4 + 1] = uint8_t(int8_t(CLAMP(int32_t(c.g * 127.0), -128, 127)));
|
||||
w[idx * 4 + 2] = uint8_t(int8_t(CLAMP(int32_t(c.b * 127.0), -128, 127)));
|
||||
w[idx * 4 + 3] = uint8_t(int8_t(CLAMP(int32_t(c.a * 127.0), -128, 127)));
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case CUSTOM_RG_HALF: {
|
||||
Vector<uint8_t> array;
|
||||
array.resize(varr_len * 4);
|
||||
uint16_t *w = (uint16_t *)array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx * 2 + 0] = Math::make_half_float(c.r);
|
||||
w[idx * 2 + 1] = Math::make_half_float(c.g);
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case CUSTOM_RGBA_HALF: {
|
||||
Vector<uint8_t> array;
|
||||
array.resize(varr_len * 8);
|
||||
uint16_t *w = (uint16_t *)array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx * 4 + 0] = Math::make_half_float(c.r);
|
||||
w[idx * 4 + 1] = Math::make_half_float(c.g);
|
||||
w[idx * 4 + 2] = Math::make_half_float(c.b);
|
||||
w[idx * 4 + 3] = Math::make_half_float(c.a);
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case CUSTOM_R_FLOAT: {
|
||||
Vector<float> array;
|
||||
array.resize(varr_len);
|
||||
float *w = (float *)array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx] = c.r;
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case CUSTOM_RG_FLOAT: {
|
||||
Vector<float> array;
|
||||
array.resize(varr_len * 2);
|
||||
float *w = (float *)array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx * 2 + 0] = c.r;
|
||||
w[idx * 2 + 1] = c.g;
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case CUSTOM_RGB_FLOAT: {
|
||||
Vector<float> array;
|
||||
array.resize(varr_len * 3);
|
||||
float *w = (float *)array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx * 3 + 0] = c.r;
|
||||
w[idx * 3 + 1] = c.g;
|
||||
w[idx * 3 + 2] = c.b;
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
case CUSTOM_RGBA_FLOAT: {
|
||||
Vector<float> array;
|
||||
array.resize(varr_len * 4);
|
||||
float *w = (float *)array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
|
||||
const Vertex &v = E->get();
|
||||
const Color &c = v.custom[idx];
|
||||
w[idx * 4 + 0] = c.r;
|
||||
w[idx * 4 + 1] = c.g;
|
||||
w[idx * 4 + 2] = c.b;
|
||||
w[idx * 4 + 3] = c.a;
|
||||
}
|
||||
|
||||
a[i] = array;
|
||||
} break;
|
||||
default: {
|
||||
} //unreachable but compiler warning anyway
|
||||
}
|
||||
} break;
|
||||
case Mesh::ARRAY_BONES: {
|
||||
int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4;
|
||||
Vector<int> array;
|
||||
array.resize(varr_len * count);
|
||||
int *w = array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += count) {
|
||||
const Vertex &v = E->get();
|
||||
|
||||
ERR_CONTINUE(v.bones.size() != 4);
|
||||
ERR_CONTINUE(v.bones.size() != count);
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int j = 0; j < count; j++) {
|
||||
w[idx + j] = v.bones[j];
|
||||
}
|
||||
}
|
||||
|
@ -379,15 +549,17 @@ Array SurfaceTool::commit_to_arrays() {
|
|||
} break;
|
||||
case Mesh::ARRAY_WEIGHTS: {
|
||||
Vector<float> array;
|
||||
array.resize(varr_len * 4);
|
||||
int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4;
|
||||
|
||||
array.resize(varr_len * count);
|
||||
float *w = array.ptrw();
|
||||
|
||||
int idx = 0;
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
|
||||
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += count) {
|
||||
const Vertex &v = E->get();
|
||||
ERR_CONTINUE(v.weights.size() != 4);
|
||||
ERR_CONTINUE(v.weights.size() != count);
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int j = 0; j < count; j++) {
|
||||
w[idx + j] = v.weights[j];
|
||||
}
|
||||
}
|
||||
|
@ -492,13 +664,13 @@ void SurfaceTool::deindex() {
|
|||
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) {
|
||||
void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat) {
|
||||
Array arr = p_existing->surface_get_arrays(p_surface);
|
||||
ERR_FAIL_COND(arr.size() != RS::ARRAY_MAX);
|
||||
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
|
||||
}
|
||||
|
||||
Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) {
|
||||
Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, uint32_t *r_format) {
|
||||
Vector<SurfaceTool::Vertex> ret;
|
||||
|
||||
Vector<Vector3> varr = p_arrays[RS::ARRAY_VERTEX];
|
||||
|
@ -509,9 +681,13 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
|
|||
Vector<Vector2> uv2arr = p_arrays[RS::ARRAY_TEX_UV2];
|
||||
Vector<int> barr = p_arrays[RS::ARRAY_BONES];
|
||||
Vector<float> warr = p_arrays[RS::ARRAY_WEIGHTS];
|
||||
Vector<float> custom_float[RS::ARRAY_CUSTOM_COUNT];
|
||||
|
||||
int vc = varr.size();
|
||||
if (vc == 0) {
|
||||
if (r_format) {
|
||||
*r_format = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -534,12 +710,40 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
|
|||
if (uv2arr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_TEX_UV2;
|
||||
}
|
||||
if (barr.size()) {
|
||||
int wcount = 0;
|
||||
if (barr.size() && warr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_BONES;
|
||||
lformat |= RS::ARRAY_FORMAT_WEIGHTS;
|
||||
|
||||
wcount = barr.size() / varr.size();
|
||||
if (wcount == 8) {
|
||||
lformat |= RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
|
||||
}
|
||||
}
|
||||
|
||||
if (warr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_WEIGHTS;
|
||||
}
|
||||
static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
|
||||
static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
|
||||
ERR_CONTINUE_MSG(p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_BYTE_ARRAY, "Extracting Byte/Half formats is not supported");
|
||||
if (p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_FLOAT32_ARRAY) {
|
||||
lformat |= custom_mask[i];
|
||||
custom_float[i] = p_arrays[RS::ARRAY_CUSTOM0 + i];
|
||||
int fmt = custom_float[i].size() / varr.size();
|
||||
if (fmt == 1) {
|
||||
lformat |= CUSTOM_R_FLOAT << custom_shift[i];
|
||||
} else if (fmt == 2) {
|
||||
lformat |= CUSTOM_RG_FLOAT << custom_shift[i];
|
||||
} else if (fmt == 3) {
|
||||
lformat |= CUSTOM_RGB_FLOAT << custom_shift[i];
|
||||
} else if (fmt == 4) {
|
||||
lformat |= CUSTOM_RGBA_FLOAT << custom_shift[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < vc; i++) {
|
||||
Vertex v;
|
||||
|
@ -565,112 +769,46 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
|
|||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_BONES) {
|
||||
Vector<int> b;
|
||||
b.resize(4);
|
||||
b.write[0] = barr[i * 4 + 0];
|
||||
b.write[1] = barr[i * 4 + 1];
|
||||
b.write[2] = barr[i * 4 + 2];
|
||||
b.write[3] = barr[i * 4 + 3];
|
||||
b.resize(wcount);
|
||||
for (int j = 0; j < wcount; j++) {
|
||||
b.write[j] = barr[i * wcount + j];
|
||||
}
|
||||
v.bones = b;
|
||||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_WEIGHTS) {
|
||||
Vector<float> w;
|
||||
w.resize(4);
|
||||
w.write[0] = warr[i * 4 + 0];
|
||||
w.write[1] = warr[i * 4 + 1];
|
||||
w.write[2] = warr[i * 4 + 2];
|
||||
w.write[3] = warr[i * 4 + 3];
|
||||
w.resize(wcount);
|
||||
for (int j = 0; j < wcount; j++) {
|
||||
w.write[j] = warr[i * wcount + j];
|
||||
}
|
||||
v.weights = w;
|
||||
}
|
||||
|
||||
for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
|
||||
if (lformat & custom_mask[j]) {
|
||||
int cc = custom_float[j].size() / varr.size();
|
||||
for (int k = 0; k < cc; k++) {
|
||||
v.custom[j][k] = custom_float[j][i * cc + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret.push_back(v);
|
||||
}
|
||||
|
||||
if (r_format) {
|
||||
*r_format = lformat;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
|
||||
Vector<Vector3> varr = arr[RS::ARRAY_VERTEX];
|
||||
Vector<Vector3> narr = arr[RS::ARRAY_NORMAL];
|
||||
Vector<float> tarr = arr[RS::ARRAY_TANGENT];
|
||||
Vector<Color> carr = arr[RS::ARRAY_COLOR];
|
||||
Vector<Vector2> uvarr = arr[RS::ARRAY_TEX_UV];
|
||||
Vector<Vector2> uv2arr = arr[RS::ARRAY_TEX_UV2];
|
||||
Vector<int> barr = arr[RS::ARRAY_BONES];
|
||||
Vector<float> warr = arr[RS::ARRAY_WEIGHTS];
|
||||
void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat) {
|
||||
Vector<Vertex> arrays = create_vertex_array_from_triangle_arrays(arr, &lformat);
|
||||
ERR_FAIL_COND(arrays.size() == 0);
|
||||
|
||||
int vc = varr.size();
|
||||
if (vc == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
lformat = 0;
|
||||
if (varr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_VERTEX;
|
||||
}
|
||||
if (narr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_NORMAL;
|
||||
}
|
||||
if (tarr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_TANGENT;
|
||||
}
|
||||
if (carr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_COLOR;
|
||||
}
|
||||
if (uvarr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_TEX_UV;
|
||||
}
|
||||
if (uv2arr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_TEX_UV2;
|
||||
}
|
||||
if (barr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_BONES;
|
||||
}
|
||||
if (warr.size()) {
|
||||
lformat |= RS::ARRAY_FORMAT_WEIGHTS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < vc; i++) {
|
||||
Vertex v;
|
||||
if (lformat & RS::ARRAY_FORMAT_VERTEX) {
|
||||
v.vertex = varr[i];
|
||||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_NORMAL) {
|
||||
v.normal = narr[i];
|
||||
}
|
||||
if (lformat & RS::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(v.tangent).normalized() * p.d;
|
||||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_COLOR) {
|
||||
v.color = carr[i];
|
||||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_TEX_UV) {
|
||||
v.uv = uvarr[i];
|
||||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_TEX_UV2) {
|
||||
v.uv2 = uv2arr[i];
|
||||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_BONES) {
|
||||
Vector<int> b;
|
||||
b.resize(4);
|
||||
b.write[0] = barr[i * 4 + 0];
|
||||
b.write[1] = barr[i * 4 + 1];
|
||||
b.write[2] = barr[i * 4 + 2];
|
||||
b.write[3] = barr[i * 4 + 3];
|
||||
v.bones = b;
|
||||
}
|
||||
if (lformat & RS::ARRAY_FORMAT_WEIGHTS) {
|
||||
Vector<float> w;
|
||||
w.resize(4);
|
||||
w.write[0] = warr[i * 4 + 0];
|
||||
w.write[1] = warr[i * 4 + 1];
|
||||
w.write[2] = warr[i * 4 + 2];
|
||||
w.write[3] = warr[i * 4 + 3];
|
||||
v.weights = w;
|
||||
}
|
||||
|
||||
r_vertex->push_back(v);
|
||||
for (int i = 0; i < arrays.size(); i++) {
|
||||
r_vertex->push_back(arrays[i]);
|
||||
}
|
||||
|
||||
//indices
|
||||
|
@ -725,7 +863,7 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
|
|||
format = 0;
|
||||
}
|
||||
|
||||
int nformat;
|
||||
uint32_t nformat;
|
||||
List<Vertex> nvertices;
|
||||
List<int> nindices;
|
||||
_create_list(p_existing, p_surface, &nvertices, &nindices, nformat);
|
||||
|
@ -975,19 +1113,48 @@ void SurfaceTool::clear() {
|
|||
vertex_array.clear();
|
||||
smooth_groups.clear();
|
||||
material.unref();
|
||||
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
|
||||
last_custom_format[i] = CUSTOM_MAX;
|
||||
}
|
||||
skin_weights = SKIN_4_WEIGHTS;
|
||||
}
|
||||
|
||||
void SurfaceTool::set_skin_weight_count(SkinWeightCount p_weights) {
|
||||
ERR_FAIL_COND(begun);
|
||||
skin_weights = p_weights;
|
||||
}
|
||||
SurfaceTool::SkinWeightCount SurfaceTool::get_skin_weight_count() const {
|
||||
return skin_weights;
|
||||
}
|
||||
|
||||
void SurfaceTool::set_custom_format(int p_index, CustomFormat p_format) {
|
||||
ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT);
|
||||
ERR_FAIL_COND(begun);
|
||||
last_custom_format[p_index] = p_format;
|
||||
}
|
||||
SurfaceTool::CustomFormat SurfaceTool::get_custom_format(int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, RS::ARRAY_CUSTOM_COUNT, CUSTOM_MAX);
|
||||
return last_custom_format[p_index];
|
||||
}
|
||||
|
||||
void SurfaceTool::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_skin_weight_count", "count"), &SurfaceTool::set_skin_weight_count);
|
||||
ClassDB::bind_method(D_METHOD("get_skin_weight_count"), &SurfaceTool::get_skin_weight_count);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_custom_format", "index", "format"), &SurfaceTool::set_custom_format);
|
||||
ClassDB::bind_method(D_METHOD("get_custom_format", "index"), &SurfaceTool::get_custom_format);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex);
|
||||
ClassDB::bind_method(D_METHOD("add_color", "color"), &SurfaceTool::add_color);
|
||||
ClassDB::bind_method(D_METHOD("add_normal", "normal"), &SurfaceTool::add_normal);
|
||||
ClassDB::bind_method(D_METHOD("add_tangent", "tangent"), &SurfaceTool::add_tangent);
|
||||
ClassDB::bind_method(D_METHOD("add_uv", "uv"), &SurfaceTool::add_uv);
|
||||
ClassDB::bind_method(D_METHOD("add_uv2", "uv2"), &SurfaceTool::add_uv2);
|
||||
ClassDB::bind_method(D_METHOD("add_bones", "bones"), &SurfaceTool::add_bones);
|
||||
ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights);
|
||||
ClassDB::bind_method(D_METHOD("set_color", "color"), &SurfaceTool::set_color);
|
||||
ClassDB::bind_method(D_METHOD("set_normal", "normal"), &SurfaceTool::set_normal);
|
||||
ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &SurfaceTool::set_tangent);
|
||||
ClassDB::bind_method(D_METHOD("set_uv", "uv"), &SurfaceTool::set_uv);
|
||||
ClassDB::bind_method(D_METHOD("set_uv2", "uv2"), &SurfaceTool::set_uv2);
|
||||
ClassDB::bind_method(D_METHOD("set_bones", "bones"), &SurfaceTool::set_bones);
|
||||
ClassDB::bind_method(D_METHOD("set_weights", "weights"), &SurfaceTool::set_weights);
|
||||
ClassDB::bind_method(D_METHOD("set_custom", "index", "custom"), &SurfaceTool::set_custom);
|
||||
ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>()));
|
||||
|
@ -1006,13 +1173,29 @@ void SurfaceTool::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from);
|
||||
ClassDB::bind_method(D_METHOD("create_from_blend_shape", "existing", "surface", "blend_shape"), &SurfaceTool::create_from_blend_shape);
|
||||
ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from);
|
||||
ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT));
|
||||
ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("commit_to_arrays"), &SurfaceTool::commit_to_arrays);
|
||||
|
||||
BIND_ENUM_CONSTANT(CUSTOM_RGBA8_UNORM);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_RGBA8_SNORM);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_RG_HALF);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_RGBA_HALF);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_R_FLOAT);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_RG_FLOAT);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_RGB_FLOAT);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_RGBA_FLOAT);
|
||||
BIND_ENUM_CONSTANT(CUSTOM_MAX);
|
||||
BIND_ENUM_CONSTANT(SKIN_4_WEIGHTS);
|
||||
BIND_ENUM_CONSTANT(SKIN_8_WEIGHTS);
|
||||
}
|
||||
|
||||
SurfaceTool::SurfaceTool() {
|
||||
first = false;
|
||||
begun = false;
|
||||
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
|
||||
last_custom_format[i] = CUSTOM_MAX;
|
||||
}
|
||||
primitive = Mesh::PRIMITIVE_LINES;
|
||||
skin_weights = SKIN_4_WEIGHTS;
|
||||
format = 0;
|
||||
}
|
||||
|
|
|
@ -49,12 +49,30 @@ public:
|
|||
Vector2 uv2;
|
||||
Vector<int> bones;
|
||||
Vector<float> weights;
|
||||
Color custom[RS::ARRAY_CUSTOM_COUNT];
|
||||
|
||||
bool operator==(const Vertex &p_vertex) const;
|
||||
|
||||
Vertex() {}
|
||||
};
|
||||
|
||||
enum CustomFormat {
|
||||
CUSTOM_RGBA8_UNORM = RS::ARRAY_CUSTOM_RGBA8_UNORM,
|
||||
CUSTOM_RGBA8_SNORM = RS::ARRAY_CUSTOM_RGBA8_SNORM,
|
||||
CUSTOM_RG_HALF = RS::ARRAY_CUSTOM_RG_HALF,
|
||||
CUSTOM_RGBA_HALF = RS::ARRAY_CUSTOM_RGBA_HALF,
|
||||
CUSTOM_R_FLOAT = RS::ARRAY_CUSTOM_R_FLOAT,
|
||||
CUSTOM_RG_FLOAT = RS::ARRAY_CUSTOM_RG_FLOAT,
|
||||
CUSTOM_RGB_FLOAT = RS::ARRAY_CUSTOM_RGB_FLOAT,
|
||||
CUSTOM_RGBA_FLOAT = RS::ARRAY_CUSTOM_RGBA_FLOAT,
|
||||
CUSTOM_MAX = RS::ARRAY_CUSTOM_MAX
|
||||
};
|
||||
|
||||
enum SkinWeightCount {
|
||||
SKIN_4_WEIGHTS,
|
||||
SKIN_8_WEIGHTS
|
||||
};
|
||||
|
||||
private:
|
||||
struct VertexHasher {
|
||||
static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx);
|
||||
|
@ -71,7 +89,7 @@ private:
|
|||
bool begun;
|
||||
bool first;
|
||||
Mesh::PrimitiveType primitive;
|
||||
int format;
|
||||
uint32_t format;
|
||||
Ref<Material> material;
|
||||
//arrays
|
||||
List<Vertex> vertex_array;
|
||||
|
@ -87,8 +105,14 @@ 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);
|
||||
SkinWeightCount skin_weights;
|
||||
|
||||
Color last_custom[RS::ARRAY_CUSTOM_COUNT];
|
||||
|
||||
CustomFormat last_custom_format[RS::ARRAY_CUSTOM_COUNT];
|
||||
|
||||
void _create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat);
|
||||
void _create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat);
|
||||
|
||||
//mikktspace callbacks
|
||||
static int mikktGetNumFaces(const SMikkTSpaceContext *pContext);
|
||||
|
@ -103,18 +127,26 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_skin_weight_count(SkinWeightCount p_weights);
|
||||
SkinWeightCount get_skin_weight_count() const;
|
||||
|
||||
void set_custom_format(int p_index, CustomFormat p_format);
|
||||
CustomFormat get_custom_format(int p_index) const;
|
||||
|
||||
void begin(Mesh::PrimitiveType p_primitive);
|
||||
|
||||
void add_vertex(const Vector3 &p_vertex);
|
||||
void add_color(Color p_color);
|
||||
void add_normal(const Vector3 &p_normal);
|
||||
void add_tangent(const Plane &p_tangent);
|
||||
void add_uv(const Vector2 &p_uv);
|
||||
void add_uv2(const Vector2 &p_uv2);
|
||||
void add_bones(const Vector<int> &p_bones);
|
||||
void add_weights(const Vector<float> &p_weights);
|
||||
void add_smooth_group(bool p_smooth);
|
||||
void set_color(Color p_color);
|
||||
void set_normal(const Vector3 &p_normal);
|
||||
void set_tangent(const Plane &p_tangent);
|
||||
void set_uv(const Vector2 &p_uv);
|
||||
void set_uv2(const Vector2 &p_uv2);
|
||||
void set_custom(int p_index, const Color &p_custom);
|
||||
void set_bones(const Vector<int> &p_bones);
|
||||
void set_weights(const Vector<float> &p_weights);
|
||||
|
||||
void add_vertex(const Vector3 &p_vertex);
|
||||
|
||||
void add_smooth_group(bool p_smooth);
|
||||
void add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>());
|
||||
|
||||
void add_index(int p_index);
|
||||
|
@ -131,14 +163,17 @@ public:
|
|||
List<Vertex> &get_vertex_array() { return vertex_array; }
|
||||
|
||||
void create_from_triangle_arrays(const Array &p_arrays);
|
||||
static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays);
|
||||
static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays, uint32_t *r_format = nullptr);
|
||||
Array commit_to_arrays();
|
||||
void create_from(const Ref<Mesh> &p_existing, int p_surface);
|
||||
void create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name);
|
||||
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>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT);
|
||||
Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = 0);
|
||||
|
||||
SurfaceTool();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(SurfaceTool::CustomFormat)
|
||||
VARIANT_ENUM_CAST(SurfaceTool::SkinWeightCount)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -119,9 +119,9 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
Vector<uint8_t> polygon_buffer;
|
||||
polygon_buffer.resize(buffer_size * sizeof(float));
|
||||
Vector<RD::VertexAttribute> descriptions;
|
||||
descriptions.resize(4);
|
||||
descriptions.resize(5);
|
||||
Vector<RID> buffers;
|
||||
buffers.resize(4);
|
||||
buffers.resize(5);
|
||||
|
||||
{
|
||||
const uint8_t *r = polygon_buffer.ptr();
|
||||
|
@ -218,7 +218,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
//bones
|
||||
if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_BONES;
|
||||
vd.stride = stride * sizeof(float);
|
||||
|
@ -226,24 +226,17 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
descriptions.write[3] = vd;
|
||||
|
||||
const int *bone_ptr = p_bones.ptr();
|
||||
const float *weight_ptr = p_weights.ptr();
|
||||
|
||||
for (uint32_t i = 0; i < vertex_count; i++) {
|
||||
uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
|
||||
uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2];
|
||||
|
||||
bone16w[0] = bone_ptr[i * 4 + 0];
|
||||
bone16w[1] = bone_ptr[i * 4 + 1];
|
||||
bone16w[2] = bone_ptr[i * 4 + 2];
|
||||
bone16w[3] = bone_ptr[i * 4 + 3];
|
||||
|
||||
weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
|
||||
weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
|
||||
weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
|
||||
weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
|
||||
}
|
||||
|
||||
base_offset += 4;
|
||||
base_offset += 2;
|
||||
} else {
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
|
@ -255,6 +248,39 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
buffers.write[3] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES);
|
||||
}
|
||||
|
||||
//weights
|
||||
if ((uint32_t)p_weights.size() == vertex_count * 4) {
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
vd.location = RS::ARRAY_WEIGHTS;
|
||||
vd.stride = stride * sizeof(float);
|
||||
|
||||
descriptions.write[4] = vd;
|
||||
|
||||
const float *weight_ptr = p_weights.ptr();
|
||||
|
||||
for (uint32_t i = 0; i < vertex_count; i++) {
|
||||
uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride];
|
||||
|
||||
weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
|
||||
weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
|
||||
weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
|
||||
weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
|
||||
}
|
||||
|
||||
base_offset += 2;
|
||||
} else {
|
||||
RD::VertexAttribute vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
vd.offset = 0;
|
||||
vd.location = RS::ARRAY_WEIGHTS;
|
||||
vd.stride = 0;
|
||||
|
||||
descriptions.write[4] = vd;
|
||||
buffers.write[4] = storage->mesh_get_default_rd_buffer(RasterizerStorageRD::DEFAULT_RD_BUFFER_BONES);
|
||||
}
|
||||
|
||||
//check that everything is as it should be
|
||||
ERR_FAIL_COND_V(base_offset != stride, 0); //bug
|
||||
}
|
||||
|
@ -1796,6 +1822,8 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
ERR_FAIL_COND(!oc);
|
||||
|
||||
Vector<Vector2> lines;
|
||||
|
||||
if (p_points.size()) {
|
||||
int lc = p_points.size() * 2;
|
||||
|
||||
lines.resize(lc - (p_closed ? 0 : 2));
|
||||
|
@ -1814,6 +1842,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
w[i * 2 + 1] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oc->line_point_count != lines.size() && oc->vertex_array.is_valid()) {
|
||||
RD::get_singleton()->free(oc->vertex_array);
|
||||
|
@ -1832,7 +1861,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
if (lines.size()) {
|
||||
Vector<uint8_t> geometry;
|
||||
Vector<uint8_t> indices;
|
||||
lc = lines.size();
|
||||
int lc = lines.size();
|
||||
|
||||
geometry.resize(lc * 6 * sizeof(float));
|
||||
indices.resize(lc * 3 * sizeof(uint16_t));
|
||||
|
@ -1902,6 +1931,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
|
||||
Vector<int> sdf_indices;
|
||||
|
||||
if (p_points.size()) {
|
||||
if (p_closed) {
|
||||
sdf_indices = Geometry2D::triangulate_polygon(p_points);
|
||||
oc->sdf_is_lines = false;
|
||||
|
@ -1916,6 +1946,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape(RID p_occluder, const Vector
|
|||
}
|
||||
oc->sdf_is_lines = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array.is_valid()) {
|
||||
RD::get_singleton()->free(oc->sdf_vertex_array);
|
||||
|
|
|
@ -2795,6 +2795,12 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
|
|||
actions.renames["FOG"] = "custom_fog";
|
||||
actions.renames["RADIANCE"] = "custom_radiance";
|
||||
actions.renames["IRRADIANCE"] = "custom_irradiance";
|
||||
actions.renames["BONE_INDICES"] = "bone_attrib";
|
||||
actions.renames["BONE_WEIGHTS"] = "weight_attrib";
|
||||
actions.renames["CUSTOM0"] = "custom0_attrib";
|
||||
actions.renames["CUSTOM1"] = "custom1_attrib";
|
||||
actions.renames["CUSTOM2"] = "custom2_attrib";
|
||||
actions.renames["CUSTOM3"] = "custom3_attrib";
|
||||
|
||||
//for light
|
||||
actions.renames["VIEW"] = "view";
|
||||
|
@ -2817,6 +2823,12 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
|
|||
actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n";
|
||||
actions.usage_defines["UV"] = "#define UV_USED\n";
|
||||
actions.usage_defines["UV2"] = "#define UV2_USED\n";
|
||||
actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n";
|
||||
actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n";
|
||||
actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n";
|
||||
actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
|
||||
actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
|
||||
actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
|
||||
actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
|
||||
actions.usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
|
||||
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
|
||||
|
|
|
@ -5336,18 +5336,19 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
|
|||
tonemap.exposure = env->exposure;
|
||||
}
|
||||
|
||||
tonemap.use_color_correction = false;
|
||||
tonemap.use_1d_color_correction = false;
|
||||
tonemap.color_correction_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
|
||||
|
||||
if (can_use_effects && env) {
|
||||
tonemap.use_bcs = env->adjustments_enabled;
|
||||
tonemap.brightness = env->adjustments_brightness;
|
||||
tonemap.contrast = env->adjustments_contrast;
|
||||
tonemap.saturation = env->adjustments_saturation;
|
||||
tonemap.use_1d_color_correction = env->use_1d_color_correction;
|
||||
if (env->adjustments_enabled && env->color_correction.is_valid()) {
|
||||
tonemap.use_color_correction = true;
|
||||
tonemap.use_1d_color_correction = env->use_1d_color_correction;
|
||||
tonemap.color_correction_texture = storage->texture_get_rd_texture(env->color_correction);
|
||||
} else {
|
||||
tonemap.use_color_correction = false;
|
||||
tonemap.color_correction_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2398,13 +2398,15 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
ERR_FAIL_COND(!mesh);
|
||||
|
||||
//ensure blend shape consistency
|
||||
ERR_FAIL_COND(mesh->blend_shape_count && p_surface.blend_shapes.size() != (int)mesh->blend_shape_count);
|
||||
ERR_FAIL_COND(mesh->blend_shape_count && p_surface.blend_shape_count != mesh->blend_shape_count);
|
||||
ERR_FAIL_COND(mesh->blend_shape_count && p_surface.bone_aabbs.size() != mesh->bone_aabbs.size());
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
//do a validation, to catch errors first
|
||||
{
|
||||
uint32_t stride = 0;
|
||||
uint32_t attrib_stride = 0;
|
||||
uint32_t skin_stride = 0;
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
|
||||
if ((p_surface.format & (1 << i))) {
|
||||
|
@ -2418,59 +2420,54 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
|
||||
} break;
|
||||
case RS::ARRAY_NORMAL: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_NORMAL) {
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
stride += sizeof(int32_t);
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_TANGENT: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_TANGENT) {
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
stride += sizeof(int32_t);
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_COLOR: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_COLOR) {
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
|
||||
attrib_stride += sizeof(int16_t) * 4;
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV) {
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
attrib_stride += sizeof(float) * 2;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV2: {
|
||||
if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV2) {
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
attrib_stride += sizeof(float) * 2;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_CUSTOM0:
|
||||
case RS::ARRAY_CUSTOM1:
|
||||
case RS::ARRAY_CUSTOM2:
|
||||
case RS::ARRAY_CUSTOM3: {
|
||||
int idx = i - RS::ARRAY_CUSTOM0;
|
||||
uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
uint32_t fmt = (p_surface.format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
|
||||
uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
|
||||
attrib_stride += fmtsize[fmt];
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_WEIGHTS:
|
||||
case RS::ARRAY_BONES: {
|
||||
//assumed weights too
|
||||
|
||||
//unique format, internally 16 bits, exposed as single array for 32
|
||||
|
||||
stride += sizeof(int32_t) * 4;
|
||||
|
||||
//uses a separate array
|
||||
bool use_8 = p_surface.format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
|
||||
skin_stride += sizeof(int16_t) * (use_8 ? 8 : 4);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int expected_size = stride * p_surface.vertex_count;
|
||||
ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
|
||||
ERR_FAIL_COND_MSG(expected_size != p_surface.vertex_data.size(), "Size of vertex data provided (" + itos(p_surface.vertex_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
|
||||
int expected_attrib_size = attrib_stride * p_surface.vertex_count;
|
||||
ERR_FAIL_COND_MSG(expected_attrib_size != p_surface.attribute_data.size(), "Size of attribute data provided (" + itos(p_surface.attribute_data.size()) + ") does not match expected (" + itos(expected_attrib_size) + ")");
|
||||
|
||||
if ((p_surface.format & RS::ARRAY_FORMAT_WEIGHTS) && (p_surface.format & RS::ARRAY_FORMAT_BONES)) {
|
||||
expected_size = skin_stride * p_surface.vertex_count;
|
||||
ERR_FAIL_COND_MSG(expected_size != p_surface.skin_data.size(), "Size of skin data provided (" + itos(p_surface.skin_data.size()) + ") does not match expected (" + itos(expected_size) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2481,6 +2478,12 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
s->primitive = p_surface.primitive;
|
||||
|
||||
s->vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.vertex_data.size(), p_surface.vertex_data);
|
||||
if (p_surface.attribute_data.size()) {
|
||||
s->attribute_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.attribute_data.size(), p_surface.attribute_data);
|
||||
}
|
||||
if (p_surface.skin_data.size()) {
|
||||
s->skin_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.skin_data.size(), p_surface.skin_data);
|
||||
}
|
||||
s->vertex_count = p_surface.vertex_count;
|
||||
|
||||
if (p_surface.index_count) {
|
||||
|
@ -2504,7 +2507,7 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
|
||||
s->aabb = p_surface.aabb;
|
||||
s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them.
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < p_surface.blend_shapes.size(); i++) {
|
||||
if (p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()) {
|
||||
memdelete(s);
|
||||
|
@ -2513,8 +2516,8 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
|
|||
RID vertex_buffer = RD::get_singleton()->vertex_buffer_create(p_surface.blend_shapes[i].size(), p_surface.blend_shapes[i]);
|
||||
s->blend_shapes.push_back(vertex_buffer);
|
||||
}
|
||||
|
||||
mesh->blend_shape_count = p_surface.blend_shapes.size();
|
||||
#endif
|
||||
mesh->blend_shape_count = p_surface.blend_shape_count;
|
||||
|
||||
if (mesh->surface_count == 0) {
|
||||
mesh->bone_aabbs = p_surface.bone_aabbs;
|
||||
|
@ -2596,6 +2599,12 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface)
|
|||
RS::SurfaceData sd;
|
||||
sd.format = s.format;
|
||||
sd.vertex_data = RD::get_singleton()->buffer_get_data(s.vertex_buffer);
|
||||
if (s.attribute_buffer.is_valid()) {
|
||||
sd.attribute_data = RD::get_singleton()->buffer_get_data(s.attribute_buffer);
|
||||
}
|
||||
if (s.skin_buffer.is_valid()) {
|
||||
sd.skin_data = RD::get_singleton()->buffer_get_data(s.skin_buffer);
|
||||
}
|
||||
sd.vertex_count = s.vertex_count;
|
||||
sd.index_count = s.index_count;
|
||||
sd.primitive = s.primitive;
|
||||
|
@ -2613,9 +2622,8 @@ RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface)
|
|||
|
||||
sd.bone_aabbs = s.bone_aabbs;
|
||||
|
||||
for (int i = 0; i < s.blend_shapes.size(); i++) {
|
||||
Vector<uint8_t> bs = RD::get_singleton()->buffer_get_data(s.blend_shapes[i]);
|
||||
sd.blend_shapes.push_back(bs);
|
||||
if (s.blend_shape_buffer.is_valid()) {
|
||||
sd.blend_shape_data = RD::get_singleton()->buffer_get_data(s.blend_shape_buffer);
|
||||
}
|
||||
|
||||
return sd;
|
||||
|
@ -2750,6 +2758,12 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) {
|
|||
for (uint32_t i = 0; i < mesh->surface_count; i++) {
|
||||
Mesh::Surface &s = *mesh->surfaces[i];
|
||||
RD::get_singleton()->free(s.vertex_buffer); //clears arrays as dependency automatically, including all versions
|
||||
if (s.attribute_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.attribute_buffer);
|
||||
}
|
||||
if (s.skin_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.skin_buffer);
|
||||
}
|
||||
if (s.versions) {
|
||||
memfree(s.versions); //reallocs, so free with memfree.
|
||||
}
|
||||
|
@ -2765,12 +2779,8 @@ void RasterizerStorageRD::mesh_clear(RID p_mesh) {
|
|||
memdelete_arr(s.lods);
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < s.blend_shapes.size(); j++) {
|
||||
RD::get_singleton()->free(s.blend_shapes[j]);
|
||||
}
|
||||
|
||||
if (s.blend_shape_base_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.blend_shape_base_buffer);
|
||||
if (s.blend_shape_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(s.blend_shape_buffer);
|
||||
}
|
||||
|
||||
memdelete(mesh->surfaces[i]);
|
||||
|
@ -2796,8 +2806,10 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
Vector<RID> buffers;
|
||||
|
||||
uint32_t stride = 0;
|
||||
uint32_t attribute_stride = 0;
|
||||
uint32_t skin_stride = 0;
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
|
||||
for (int i = 0; i < RS::ARRAY_INDEX; i++) {
|
||||
RD::VertexAttribute vd;
|
||||
RID buffer;
|
||||
vd.location = i;
|
||||
|
@ -2805,6 +2817,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
if (!(s->format & (1 << i))) {
|
||||
// Not supplied by surface, use default value
|
||||
buffer = mesh_default_rd_buffers[i];
|
||||
vd.stride = 0;
|
||||
switch (i) {
|
||||
case RS::ARRAY_VERTEX: {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
|
||||
|
@ -2827,20 +2840,31 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
case RS::ARRAY_TEX_UV2: {
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
} break;
|
||||
case RS::ARRAY_CUSTOM0:
|
||||
case RS::ARRAY_CUSTOM1:
|
||||
case RS::ARRAY_CUSTOM2:
|
||||
case RS::ARRAY_CUSTOM3: {
|
||||
//assumed weights too
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
} break;
|
||||
case RS::ARRAY_BONES: {
|
||||
//assumed weights too
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
} break;
|
||||
case RS::ARRAY_WEIGHTS: {
|
||||
//assumed weights too
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
//Supplied, use it
|
||||
|
||||
vd.offset = stride;
|
||||
vd.stride = 1; //mark that it needs a stride set
|
||||
buffer = s->vertex_buffer;
|
||||
vd.stride = 1; //mark that it needs a stride set (default uses 0)
|
||||
|
||||
switch (i) {
|
||||
case RS::ARRAY_VERTEX: {
|
||||
vd.offset = stride;
|
||||
|
||||
if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
stride += sizeof(float) * 2;
|
||||
|
@ -2849,71 +2873,80 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
stride += sizeof(float) * 3;
|
||||
}
|
||||
|
||||
buffer = s->vertex_buffer;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_NORMAL: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_NORMAL) {
|
||||
vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
vd.offset = stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||
|
||||
stride += sizeof(uint32_t);
|
||||
buffer = s->vertex_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_TANGENT: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_TANGENT) {
|
||||
vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
vd.offset = stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||
stride += sizeof(uint32_t);
|
||||
buffer = s->vertex_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_COLOR: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_COLOR) {
|
||||
vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
stride += sizeof(int8_t) * 4;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
stride += sizeof(float) * 4;
|
||||
}
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
attribute_stride += sizeof(int16_t) * 4;
|
||||
buffer = s->attribute_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_TEX_UV) {
|
||||
vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
attribute_stride += sizeof(float) * 2;
|
||||
buffer = s->attribute_buffer;
|
||||
|
||||
} break;
|
||||
case RS::ARRAY_TEX_UV2: {
|
||||
if (s->format & RS::ARRAY_COMPRESS_TEX_UV2) {
|
||||
vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
|
||||
stride += sizeof(int16_t) * 2;
|
||||
} else {
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
stride += sizeof(float) * 2;
|
||||
}
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
attribute_stride += sizeof(float) * 2;
|
||||
buffer = s->attribute_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_CUSTOM0:
|
||||
case RS::ARRAY_CUSTOM1:
|
||||
case RS::ARRAY_CUSTOM2:
|
||||
case RS::ARRAY_CUSTOM3: {
|
||||
vd.offset = attribute_stride;
|
||||
|
||||
int idx = i - RS::ARRAY_CUSTOM0;
|
||||
uint32_t fmt_shift[RS::ARRAY_CUSTOM_COUNT] = { RS::ARRAY_FORMAT_CUSTOM0_SHIFT, RS::ARRAY_FORMAT_CUSTOM1_SHIFT, RS::ARRAY_FORMAT_CUSTOM2_SHIFT, RS::ARRAY_FORMAT_CUSTOM3_SHIFT };
|
||||
uint32_t fmt = (s->format >> fmt_shift[idx]) & RS::ARRAY_FORMAT_CUSTOM_MASK;
|
||||
uint32_t fmtsize[RS::ARRAY_CUSTOM_MAX] = { 4, 4, 4, 8, 4, 8, 12, 16 };
|
||||
RD::DataFormat fmtrd[RS::ARRAY_CUSTOM_MAX] = { RD::DATA_FORMAT_R8G8B8A8_UNORM, RD::DATA_FORMAT_R8G8B8A8_SNORM, RD::DATA_FORMAT_R16G16_SFLOAT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, RD::DATA_FORMAT_R32_SFLOAT, RD::DATA_FORMAT_R32G32_SFLOAT, RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::DATA_FORMAT_R32G32B32A32_SFLOAT };
|
||||
vd.format = fmtrd[fmt];
|
||||
attribute_stride += fmtsize[fmt];
|
||||
buffer = s->attribute_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_BONES: {
|
||||
//assumed weights too
|
||||
vd.offset = skin_stride;
|
||||
|
||||
//unique format, internally 16 bits, exposed as single array for 32
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
stride += sizeof(int32_t) * 4;
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
|
||||
skin_stride += sizeof(int16_t) * 4;
|
||||
buffer = s->skin_buffer;
|
||||
} break;
|
||||
case RS::ARRAY_WEIGHTS: {
|
||||
vd.offset = skin_stride;
|
||||
|
||||
vd.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
|
||||
skin_stride += sizeof(int16_t) * 4;
|
||||
buffer = s->skin_buffer;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(p_input_mask & (1 << i))) {
|
||||
continue; // Shader does not need this, skip it
|
||||
continue; // Shader does not need this, skip it (but computing stride was important anyway)
|
||||
}
|
||||
|
||||
attributes.push_back(vd);
|
||||
|
@ -2922,8 +2955,17 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
|
|||
|
||||
//update final stride
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
if (attributes[i].stride == 1) {
|
||||
if (attributes[i].stride == 0) {
|
||||
continue; //default location
|
||||
}
|
||||
int loc = attributes[i].location;
|
||||
|
||||
if (loc < RS::ARRAY_COLOR) {
|
||||
attributes.write[i].stride = stride;
|
||||
} else if (loc < RS::ARRAY_BONES) {
|
||||
attributes.write[i].stride = attribute_stride;
|
||||
} else {
|
||||
attributes.write[i].stride = skin_stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8263,6 +8305,19 @@ RasterizerStorageRD::RasterizerStorageRD() {
|
|||
mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
|
||||
buffer.resize(sizeof(float) * 4);
|
||||
{
|
||||
uint8_t *w = buffer.ptrw();
|
||||
float *fptr = (float *)w;
|
||||
fptr[0] = 0.0;
|
||||
fptr[1] = 0.0;
|
||||
fptr[2] = 0.0;
|
||||
fptr[3] = 0.0;
|
||||
}
|
||||
mesh_default_rd_buffers[DEFAULT_RD_BUFFER_CUSTOM0 + i] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
|
||||
}
|
||||
|
||||
{ //bones
|
||||
buffer.resize(sizeof(uint32_t) * 4);
|
||||
{
|
||||
|
|
|
@ -170,6 +170,10 @@ public:
|
|||
DEFAULT_RD_BUFFER_COLOR,
|
||||
DEFAULT_RD_BUFFER_TEX_UV,
|
||||
DEFAULT_RD_BUFFER_TEX_UV2,
|
||||
DEFAULT_RD_BUFFER_CUSTOM0,
|
||||
DEFAULT_RD_BUFFER_CUSTOM1,
|
||||
DEFAULT_RD_BUFFER_CUSTOM2,
|
||||
DEFAULT_RD_BUFFER_CUSTOM3,
|
||||
DEFAULT_RD_BUFFER_BONES,
|
||||
DEFAULT_RD_BUFFER_WEIGHTS,
|
||||
DEFAULT_RD_BUFFER_MAX,
|
||||
|
@ -378,6 +382,8 @@ private:
|
|||
uint32_t format = 0;
|
||||
|
||||
RID vertex_buffer;
|
||||
RID attribute_buffer;
|
||||
RID skin_buffer;
|
||||
uint32_t vertex_count = 0;
|
||||
|
||||
// A different pipeline needs to be allocated
|
||||
|
@ -414,8 +420,7 @@ private:
|
|||
|
||||
Vector<AABB> bone_aabbs;
|
||||
|
||||
Vector<RID> blend_shapes;
|
||||
RID blend_shape_base_buffer; //source buffer goes here when using blend shapes, and main one is uncompressed
|
||||
RID blend_shape_buffer;
|
||||
|
||||
RID material;
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ layout(location = 0) in vec2 vertex_attrib;
|
|||
layout(location = 3) in vec4 color_attrib;
|
||||
layout(location = 4) in vec2 uv_attrib;
|
||||
|
||||
layout(location = 6) in uvec4 bones_attrib;
|
||||
layout(location = 10) in uvec4 bone_attrib;
|
||||
layout(location = 11) in vec4 weight_attrib;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -61,6 +62,7 @@ void main() {
|
|||
color = vec4(unpackHalf2x16(draw_data.colors[4]), unpackHalf2x16(draw_data.colors[5]));
|
||||
}
|
||||
uvec4 bones = uvec4(0, 0, 0, 0);
|
||||
vec4 bone_weights = vec4(0.0);
|
||||
|
||||
#elif defined(USE_ATTRIBUTES)
|
||||
|
||||
|
@ -68,7 +70,8 @@ void main() {
|
|||
vec4 color = color_attrib;
|
||||
vec2 uv = uv_attrib;
|
||||
|
||||
uvec4 bones = bones_attrib;
|
||||
uvec4 bones = bone_attrib;
|
||||
vec4 bone_weights = weight_attrib;
|
||||
#else
|
||||
|
||||
vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
|
||||
|
|
|
@ -24,7 +24,29 @@ layout(location = 4) in vec2 uv_attrib;
|
|||
layout(location = 5) in vec2 uv2_attrib;
|
||||
#endif
|
||||
|
||||
layout(location = 6) in uvec4 bone_attrib; // always bound, even if unused
|
||||
#if defined(CUSTOM0_USED)
|
||||
layout(location = 6) in vec4 custom0_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM1_USED)
|
||||
layout(location = 7) in vec4 custom1_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM2_USED)
|
||||
layout(location = 8) in vec4 custom2_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM3_USED)
|
||||
layout(location = 9) in vec4 custom3_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(BONES_USED)
|
||||
layout(location = 10) in uvec4 bone_attrib;
|
||||
#endif
|
||||
|
||||
#if defined(WEIGHTS_USED)
|
||||
layout(location = 11) in vec4 weight_attrib;
|
||||
#endif
|
||||
|
||||
/* Varyings */
|
||||
|
||||
|
@ -116,14 +138,15 @@ void main() {
|
|||
}
|
||||
|
||||
vec3 vertex = vertex_attrib;
|
||||
vec3 normal = normal_attrib;
|
||||
vec3 normal = normal_attrib * 2.0 - 1.0;
|
||||
|
||||
#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
||||
vec3 tangent = tangent_attrib.xyz;
|
||||
float binormalf = tangent_attrib.a;
|
||||
vec3 tangent = tangent_attrib.xyz * 2.0 - 1.0;
|
||||
float binormalf = tangent_attrib.a * 2.0 - 1.0;
|
||||
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_SKELETON)) {
|
||||
//multimesh, instances are for it
|
||||
|
||||
|
@ -147,7 +170,7 @@ void main() {
|
|||
binormal = (vec4(binormal, 0.0) * m).xyz;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
uv_interp = uv_attrib;
|
||||
|
||||
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
|
||||
|
|
|
@ -67,6 +67,12 @@ ShaderTypes::ShaderTypes() {
|
|||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = constt(ShaderLanguage::TYPE_INT);
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4);
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_INDICES"] = ShaderLanguage::TYPE_UVEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["BONE_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM0"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM1"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM2"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["CUSTOM3"] = ShaderLanguage::TYPE_VEC4;
|
||||
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].can_discard = false;
|
||||
|
||||
//builtins
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,7 +52,7 @@ class RenderingServer : public Object {
|
|||
|
||||
void _camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
|
||||
void _canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate = Color(1, 1, 1));
|
||||
Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const;
|
||||
Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const;
|
||||
|
||||
protected:
|
||||
RID _make_test_cube();
|
||||
|
@ -61,7 +61,7 @@ protected:
|
|||
RID white_texture;
|
||||
RID test_material;
|
||||
|
||||
Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, Vector<uint8_t> &r_vertex_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb);
|
||||
Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb);
|
||||
|
||||
static RenderingServer *(*create_func)();
|
||||
static void _bind_methods();
|
||||
|
@ -199,16 +199,36 @@ public:
|
|||
/* MESH API */
|
||||
|
||||
enum ArrayType {
|
||||
ARRAY_VERTEX = 0,
|
||||
ARRAY_NORMAL = 1,
|
||||
ARRAY_TANGENT = 2,
|
||||
ARRAY_COLOR = 3,
|
||||
ARRAY_TEX_UV = 4,
|
||||
ARRAY_TEX_UV2 = 5,
|
||||
ARRAY_BONES = 6,
|
||||
ARRAY_WEIGHTS = 7,
|
||||
ARRAY_INDEX = 8,
|
||||
ARRAY_MAX = 9
|
||||
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
|
||||
ARRAY_NORMAL = 1, // A2B10G10R10
|
||||
ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal
|
||||
ARRAY_COLOR = 3, // RGBA16F
|
||||
ARRAY_TEX_UV = 4, // RG32F
|
||||
ARRAY_TEX_UV2 = 5, // RG32F
|
||||
ARRAY_CUSTOM0 = 6, // depends on ArrayCustomFormat
|
||||
ARRAY_CUSTOM1 = 7,
|
||||
ARRAY_CUSTOM2 = 8,
|
||||
ARRAY_CUSTOM3 = 9,
|
||||
ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights)
|
||||
ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights)
|
||||
ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF
|
||||
ARRAY_MAX = 13
|
||||
};
|
||||
|
||||
enum {
|
||||
ARRAY_CUSTOM_COUNT = ARRAY_BONES - ARRAY_CUSTOM0
|
||||
};
|
||||
|
||||
enum ArrayCustomFormat {
|
||||
ARRAY_CUSTOM_RGBA8_UNORM,
|
||||
ARRAY_CUSTOM_RGBA8_SNORM,
|
||||
ARRAY_CUSTOM_RG_HALF,
|
||||
ARRAY_CUSTOM_RGBA_HALF,
|
||||
ARRAY_CUSTOM_R_FLOAT,
|
||||
ARRAY_CUSTOM_RG_FLOAT,
|
||||
ARRAY_CUSTOM_RGB_FLOAT,
|
||||
ARRAY_CUSTOM_RGBA_FLOAT,
|
||||
ARRAY_CUSTOM_MAX
|
||||
};
|
||||
|
||||
enum ArrayFormat {
|
||||
|
@ -219,21 +239,29 @@ public:
|
|||
ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR,
|
||||
ARRAY_FORMAT_TEX_UV = 1 << ARRAY_TEX_UV,
|
||||
ARRAY_FORMAT_TEX_UV2 = 1 << ARRAY_TEX_UV2,
|
||||
ARRAY_FORMAT_CUSTOM0 = 1 << ARRAY_CUSTOM0,
|
||||
ARRAY_FORMAT_CUSTOM1 = 1 << ARRAY_CUSTOM1,
|
||||
ARRAY_FORMAT_CUSTOM2 = 1 << ARRAY_CUSTOM2,
|
||||
ARRAY_FORMAT_CUSTOM3 = 1 << ARRAY_CUSTOM3,
|
||||
ARRAY_FORMAT_BONES = 1 << ARRAY_BONES,
|
||||
ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS,
|
||||
ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX,
|
||||
|
||||
ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1),
|
||||
ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE),
|
||||
ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2,
|
||||
ARRAY_FORMAT_BLEND_SHAPE_MASK = ~(ARRAY_FORMAT_COLOR | ARRAY_FORMAT_TEX_UV | ARRAY_FORMAT_TEX_UV2 | ARRAY_FORMAT_BONES | ARRAY_FORMAT_WEIGHTS | ARRAY_FORMAT_CUSTOM0 | ARRAY_FORMAT_CUSTOM1 | ARRAY_FORMAT_CUSTOM2 | ARRAY_FORMAT_CUSTOM3 | ARRAY_FORMAT_INDEX),
|
||||
|
||||
ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1,
|
||||
ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3,
|
||||
ARRAY_FORMAT_CUSTOM_BASE = (ARRAY_INDEX + 1),
|
||||
ARRAY_FORMAT_CUSTOM_BITS = 3,
|
||||
ARRAY_FORMAT_CUSTOM0_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + 0),
|
||||
ARRAY_FORMAT_CUSTOM1_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS),
|
||||
ARRAY_FORMAT_CUSTOM2_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * 2),
|
||||
ARRAY_FORMAT_CUSTOM3_SHIFT = (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * 3),
|
||||
|
||||
ARRAY_FORMAT_CUSTOM_MASK = 0x7,
|
||||
ARRAY_COMPRESS_FLAGS_BASE = (ARRAY_INDEX + 1 + 12),
|
||||
|
||||
ARRAY_FLAG_USE_2D_VERTICES = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 0),
|
||||
ARRAY_FLAG_USE_DYNAMIC_UPDATE = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 1),
|
||||
ARRAY_FLAG_USE_8_BONE_WEIGHTS = 1 << (ARRAY_COMPRESS_FLAGS_BASE + 2),
|
||||
};
|
||||
|
||||
enum PrimitiveType {
|
||||
|
@ -249,11 +277,15 @@ public:
|
|||
PrimitiveType primitive = PRIMITIVE_MAX;
|
||||
|
||||
uint32_t format = 0;
|
||||
Vector<uint8_t> vertex_data;
|
||||
Vector<uint8_t> vertex_data; // vertex, normal, tangent (change with skinning, blendshape)
|
||||
Vector<uint8_t> attribute_data; // color,uv, uv2, custom0-3
|
||||
Vector<uint8_t> skin_data; // bone index, bone weight
|
||||
uint32_t vertex_count = 0;
|
||||
Vector<uint8_t> index_data;
|
||||
uint32_t index_count = 0;
|
||||
|
||||
uint32_t blend_shape_count = 0;
|
||||
|
||||
AABB aabb;
|
||||
struct LOD {
|
||||
float edge_length;
|
||||
|
@ -262,7 +294,7 @@ public:
|
|||
Vector<LOD> lods;
|
||||
Vector<AABB> bone_aabbs;
|
||||
|
||||
Vector<Vector<uint8_t>> blend_shapes;
|
||||
Vector<uint8_t> blend_shape_data;
|
||||
|
||||
RID material;
|
||||
};
|
||||
|
@ -270,17 +302,20 @@ public:
|
|||
virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces) = 0;
|
||||
virtual RID mesh_create() = 0;
|
||||
|
||||
virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const;
|
||||
virtual uint32_t mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const;
|
||||
virtual uint32_t mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_array_index) const;
|
||||
virtual uint32_t mesh_surface_get_format_vertex_stride(uint32_t p_format, int p_vertex_len) const;
|
||||
virtual uint32_t mesh_surface_get_format_attribute_stride(uint32_t p_format, int p_vertex_len) const;
|
||||
virtual uint32_t mesh_surface_get_format_skin_stride(uint32_t p_format, int p_vertex_len) const;
|
||||
|
||||
/// Returns stride
|
||||
virtual uint32_t mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const;
|
||||
virtual Error mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT);
|
||||
virtual void mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t &r_vertex_element_size, uint32_t &r_attrib_element_size, uint32_t &r_skin_element_size) const;
|
||||
virtual Error mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = 0);
|
||||
Array mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const;
|
||||
Array mesh_surface_get_arrays(RID p_mesh, int p_surface) const;
|
||||
Array mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const;
|
||||
Dictionary mesh_surface_get_lods(RID p_mesh, int p_surface) const;
|
||||
|
||||
virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT);
|
||||
virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_compress_format = 0);
|
||||
virtual void mesh_add_surface(RID p_mesh, const SurfaceData &p_surface) = 0;
|
||||
|
||||
virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0;
|
||||
|
|
Loading…
Reference in New Issue