summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/ustring.h2
-rw-r--r--editor/import/editor_import_collada.cpp1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp2
-rw-r--r--modules/csg/csg_shape.cpp2
-rw-r--r--platform/osx/export/export.cpp166
-rw-r--r--platform/windows/os_windows.cpp38
-rw-r--r--platform/windows/os_windows.h1
-rw-r--r--scene/3d/cpu_particles.cpp2
-rw-r--r--scene/3d/listener.h2
-rw-r--r--scene/gui/rich_text_label.cpp11
-rw-r--r--scene/main/viewport.cpp6
-rw-r--r--scene/resources/surface_tool.cpp104
-rw-r--r--scene/resources/surface_tool.h1
13 files changed, 255 insertions, 83 deletions
diff --git a/core/ustring.h b/core/ustring.h
index d2766ec7a3..8e4dbd8031 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -63,7 +63,7 @@ public:
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
const char *get_data() const;
- operator const char *() { return get_data(); };
+ operator const char *() const { return get_data(); };
};
typedef wchar_t CharType;
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index cdc35a98e2..8e69090da3 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -1191,6 +1191,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
if (collada.state.mesh_data_map.has(meshid)) {
Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
+ mesh->set_name(meshdata.name);
Error err = _create_mesh_surfaces(false, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false);
ERR_FAIL_COND_V(err, err);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index a5563c0497..cc5f50a834 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -3238,7 +3238,7 @@ bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const P
if (mesh != NULL) {
MeshInstance *mesh_instance = memnew(MeshInstance);
mesh_instance->set_mesh(mesh);
- mesh_instance->set_name(mesh->get_name());
+ mesh_instance->set_name(path.get_file().get_basename());
instanced_scene = mesh_instance;
} else {
if (!scene.is_valid()) { // invalid scene
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index a4c34e7583..4e35014459 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -47,6 +47,7 @@ void CSGShape::set_use_collision(bool p_enable) {
PhysicsServer::get_singleton()->body_set_state(root_collision_instance, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
PhysicsServer::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
+ PhysicsServer::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
_make_dirty(); //force update
} else {
PhysicsServer::get_singleton()->free(root_collision_instance);
@@ -468,6 +469,7 @@ void CSGShape::_notification(int p_what) {
PhysicsServer::get_singleton()->body_set_state(root_collision_instance, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
PhysicsServer::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
+ PhysicsServer::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
}
_make_dirty();
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index f27c042637..12a0193521 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -139,10 +139,76 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false));
}
+void _rgba8_to_packbits_encode(int p_ch, int p_size, PoolVector<uint8_t> &p_source, Vector<uint8_t> &p_dest) {
+
+ int src_len = p_size * p_size;
+
+ Vector<uint8_t> result;
+ result.resize(src_len * 1.25); //temp vector for rle encoded data, make it 25% larger for worst case scenario
+ int res_size = 0;
+
+ uint8_t buf[128];
+ int buf_size = 0;
+
+ int i = 0;
+ while (i < src_len) {
+ uint8_t cur = p_source.read()[i * 4 + p_ch];
+
+ if (i < src_len - 2) {
+
+ if ((p_source.read()[(i + 1) * 4 + p_ch] == cur) && (p_source.read()[(i + 2) * 4 + p_ch] == cur)) {
+ if (buf_size > 0) {
+ result.write[res_size++] = (uint8_t)(buf_size - 1);
+ copymem(&result.write[res_size], &buf, buf_size);
+ res_size += buf_size;
+ buf_size = 0;
+ }
+
+ uint8_t lim = i + 130 >= src_len ? src_len - i - 1 : 130;
+ bool hit_lim = true;
+
+ for (int j = 3; j <= lim; j++) {
+ if (p_source.read()[(i + j) * 4 + p_ch] != cur) {
+ hit_lim = false;
+ i = i + j - 1;
+ result.write[res_size++] = (uint8_t)(j - 3 + 0x80);
+ result.write[res_size++] = cur;
+ break;
+ }
+ }
+ if (hit_lim) {
+ result.write[res_size++] = (uint8_t)(lim - 3 + 0x80);
+ result.write[res_size++] = cur;
+ i = i + lim;
+ }
+ } else {
+ buf[buf_size++] = cur;
+ if (buf_size == 128) {
+ result.write[res_size++] = (uint8_t)(buf_size - 1);
+ copymem(&result.write[res_size], &buf, buf_size);
+ res_size += buf_size;
+ buf_size = 0;
+ }
+ }
+ } else {
+ buf[buf_size++] = cur;
+ result.write[res_size++] = (uint8_t)(buf_size - 1);
+ copymem(&result.write[res_size], &buf, buf_size);
+ res_size += buf_size;
+ buf_size = 0;
+ }
+
+ i++;
+ }
+
+ int ofs = p_dest.size();
+ p_dest.resize(p_dest.size() + res_size);
+ copymem(&p_dest.write[ofs], result.ptr(), res_size);
+}
+
void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
Ref<ImageTexture> it = memnew(ImageTexture);
- int size = 512;
Vector<uint8_t> data;
@@ -152,32 +218,82 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
data.write[2] = 'n';
data.write[3] = 's';
- const char *name[] = { "ic09", "ic08", "ic07", "icp6", "icp5", "icp4" };
- int index = 0;
-
- while (size >= 16) {
-
+ struct MacOSIconInfo {
+ const char *name;
+ const char *mask_name;
+ bool is_png;
+ int size;
+ };
+
+ static const MacOSIconInfo icon_infos[] = {
+ { "ic10", "", true, 1024 }, //1024x1024 32-bit PNG and 512x512@2x 32-bit "retina" PNG
+ { "ic09", "", true, 512 }, //512×512 32-bit PNG
+ { "ic14", "", true, 512 }, //256x256@2x 32-bit "retina" PNG
+ { "ic08", "", true, 256 }, //256×256 32-bit PNG
+ { "ic13", "", true, 256 }, //128x128@2x 32-bit "retina" PNG
+ { "ic07", "", true, 128 }, //128x128 32-bit PNG
+ { "ic12", "", true, 64 }, //32x32@2x 32-bit "retina" PNG
+ { "ic11", "", true, 32 }, //16x16@2x 32-bit "retina" PNG
+ { "il32", "l8mk", false, 32 }, //32x32 24-bit RLE + 8-bit uncompressed mask
+ { "is32", "s8mk", false, 16 } //16x16 24-bit RLE + 8-bit uncompressed mask
+ };
+
+ for (unsigned int i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy?
copy->convert(Image::FORMAT_RGBA8);
- copy->resize(size, size);
- it->create_from_image(copy);
- String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png");
- ResourceSaver::save(path, it);
-
- FileAccess *f = FileAccess::open(path, FileAccess::READ);
- ERR_FAIL_COND(!f);
-
- int ofs = data.size();
- uint32_t len = f->get_len();
- data.resize(data.size() + len + 8);
- f->get_buffer(&data.write[ofs + 8], len);
- memdelete(f);
- len += 8;
- len = BSWAP32(len);
- copymem(&data.write[ofs], name[index], 4);
- encode_uint32(len, &data.write[ofs + 4]);
- index++;
- size /= 2;
+ copy->resize(icon_infos[i].size, icon_infos[i].size);
+
+ if (icon_infos[i].is_png) {
+ //encode png icon
+ it->create_from_image(copy);
+ String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png");
+ ResourceSaver::save(path, it);
+
+ FileAccess *f = FileAccess::open(path, FileAccess::READ);
+ ERR_FAIL_COND(!f);
+
+ int ofs = data.size();
+ uint32_t len = f->get_len();
+ data.resize(data.size() + len + 8);
+ f->get_buffer(&data.write[ofs + 8], len);
+ memdelete(f);
+ len += 8;
+ len = BSWAP32(len);
+ copymem(&data.write[ofs], icon_infos[i].name, 4);
+ encode_uint32(len, &data.write[ofs + 4]);
+ } else {
+ PoolVector<uint8_t> src_data = copy->get_data();
+
+ //encode 24bit RGB RLE icon
+ {
+ int ofs = data.size();
+ data.resize(data.size() + 8);
+
+ _rgba8_to_packbits_encode(0, icon_infos[i].size, src_data, data); // encode R
+ _rgba8_to_packbits_encode(1, icon_infos[i].size, src_data, data); // encode G
+ _rgba8_to_packbits_encode(2, icon_infos[i].size, src_data, data); // encode B
+
+ int len = data.size() - ofs;
+ len = BSWAP32(len);
+ copymem(&data.write[ofs], icon_infos[i].name, 4);
+ encode_uint32(len, &data.write[ofs + 4]);
+ }
+
+ //encode 8bit mask uncompressed icon
+ {
+ int ofs = data.size();
+ int len = copy->get_width() * copy->get_height();
+ data.resize(data.size() + len + 8);
+
+ for (int j = 0; j < len; j++) {
+ data.write[ofs + 8 + j] = src_data.read()[j * 4 + 3];
+ }
+ len += 8;
+ len = BSWAP32(len);
+ copymem(&data.write[ofs], icon_infos[i].mask_name, 4);
+ encode_uint32(len, &data.write[ofs + 4]);
+ }
+ }
}
uint32_t total_len = data.size();
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index bdf459fd83..55d2bb2153 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -727,16 +727,28 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
} break;
+ case WM_MOVE: {
+ if (!IsIconic(hWnd)) {
+ int x = LOWORD(lParam);
+ int y = HIWORD(lParam);
+ last_pos = Point2(x, y);
+ }
+ } break;
+
case WM_SIZE: {
- int window_w = LOWORD(lParam);
- int window_h = HIWORD(lParam);
- if (window_w > 0 && window_h > 0 && !preserve_window_size) {
- video_mode.width = window_w;
- video_mode.height = window_h;
- } else {
- preserve_window_size = false;
- set_window_size(Size2(video_mode.width, video_mode.height));
+ // Ignore size when a SIZE_MINIMIZED event is triggered
+ if (wParam != SIZE_MINIMIZED) {
+ int window_w = LOWORD(lParam);
+ int window_h = HIWORD(lParam);
+ if (window_w > 0 && window_h > 0 && !preserve_window_size) {
+ video_mode.width = window_w;
+ video_mode.height = window_h;
+ } else {
+ preserve_window_size = false;
+ set_window_size(Size2(video_mode.width, video_mode.height));
+ }
}
+
if (wParam == SIZE_MAXIMIZED) {
maximized = true;
minimized = false;
@@ -1685,6 +1697,10 @@ int OS_Windows::get_screen_dpi(int p_screen) const {
Point2 OS_Windows::get_window_position() const {
+ if (minimized) {
+ return last_pos;
+ }
+
RECT r;
GetWindowRect(hWnd, &r);
return Point2(r.left, r.top);
@@ -1705,9 +1721,15 @@ void OS_Windows::set_window_position(const Point2 &p_position) {
ClientToScreen(hWnd, (POINT *)&rect.right);
ClipCursor(&rect);
}
+
+ last_pos = p_position;
}
Size2 OS_Windows::get_window_size() const {
+ if (minimized) {
+ return Size2(video_mode.width, video_mode.height);
+ }
+
RECT r;
if (GetClientRect(hWnd, &r)) { // Only area inside of window border
return Size2(r.right - r.left, r.bottom - r.top);
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 6aadd6994c..d09ade4daa 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -93,6 +93,7 @@ class OS_Windows : public OS {
HDC hDC; // Private GDI Device Context
HINSTANCE hInstance; // Holds The Instance Of The Application
HWND hWnd;
+ Point2 last_pos;
HBITMAP hBitmap; //DIB section for layered window
uint8_t *dib_data;
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index 0966a344cc..b07848e02e 100644
--- a/scene/3d/cpu_particles.cpp
+++ b/scene/3d/cpu_particles.cpp
@@ -217,7 +217,7 @@ String CPUParticles::get_configuration_warning() const {
if (!mesh_found) {
if (warnings != String())
warnings += "\n";
- warnings += "- " + TTR("Nothing is visible because no mesh has not been assigned.");
+ warnings += "- " + TTR("Nothing is visible because no mesh has been assigned.");
}
if (!anim_material_found && (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 ||
diff --git a/scene/3d/listener.h b/scene/3d/listener.h
index 8047971ebd..9901f7635c 100644
--- a/scene/3d/listener.h
+++ b/scene/3d/listener.h
@@ -71,8 +71,6 @@ public:
void set_visible_layers(uint32_t p_layers);
uint32_t get_visible_layers() const;
- Vector<Plane> get_frustum() const;
-
Listener();
~Listener();
};
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 17de346f51..490013d813 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -765,19 +765,17 @@ void RichTextLabel::_update_scroll() {
if (exceeds) {
scroll_visible = true;
- main->first_invalid_line = 0;
scroll_w = vscroll->get_combined_minimum_size().width;
vscroll->show();
vscroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -scroll_w);
- _validate_line_caches(main);
-
} else {
-
scroll_visible = false;
- vscroll->hide();
scroll_w = 0;
- _validate_line_caches(main);
+ vscroll->hide();
}
+
+ main->first_invalid_line = 0; //invalidate ALL
+ _validate_line_caches(main);
}
}
@@ -1616,7 +1614,6 @@ void RichTextLabel::clear() {
main->lines.clear();
main->lines.resize(1);
main->first_invalid_line = 0;
- scroll_w = 0;
update();
selection.click = NULL;
selection.active = false;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index fd584e82ad..3e27c86c67 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1747,7 +1747,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
mb->set_position(pos);
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
+ if (ScriptDebugger::get_singleton() && gui.mouse_focus) {
Array arr;
arr.push_back(gui.mouse_focus->get_path());
@@ -1850,7 +1850,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.mouse_focus = NULL;
}
- if (mouse_focus->can_process()) {
+ if (mouse_focus && mouse_focus->can_process()) {
_gui_call_input(mouse_focus, mb);
}
@@ -2065,7 +2065,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
OS::get_singleton()->set_cursor_shape((OS::CursorShape)cursor_shape);
- if (over->can_process()) {
+ if (over && over->can_process()) {
_gui_call_input(over, mm);
}
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 5d4c7861e3..9907636e91 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -764,10 +764,22 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
}
//mikktspace callbacks
+namespace {
+struct TangentGenerationContextUserData {
+ Vector<List<SurfaceTool::Vertex>::Element *> vertices;
+ Vector<List<int>::Element *> indices;
+};
+} // namespace
+
int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
- Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
- return varr.size() / 3;
+ TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+
+ if (triangle_data.indices.size() > 0) {
+ return triangle_data.indices.size() / 3;
+ } else {
+ return triangle_data.vertices.size() / 3;
+ }
}
int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
@@ -775,8 +787,17 @@ int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, c
}
void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
- Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
- Vector3 v = varr[iFace * 3 + iVert]->get().vertex;
+ TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+ Vector3 v;
+ if (triangle_data.indices.size() > 0) {
+ int index = triangle_data.indices[iFace * 3 + iVert]->get();
+ if (index < triangle_data.vertices.size()) {
+ v = triangle_data.vertices[index]->get().vertex;
+ }
+ } else {
+ v = triangle_data.vertices[iFace * 3 + iVert]->get().vertex;
+ }
+
fvPosOut[0] = v.x;
fvPosOut[1] = v.y;
fvPosOut[2] = v.z;
@@ -784,38 +805,56 @@ void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvP
void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) {
- Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
- Vector3 v = varr[iFace * 3 + iVert]->get().normal;
+ TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+ Vector3 v;
+ if (triangle_data.indices.size() > 0) {
+ int index = triangle_data.indices[iFace * 3 + iVert]->get();
+ if (index < triangle_data.vertices.size()) {
+ v = triangle_data.vertices[index]->get().normal;
+ }
+ } else {
+ v = triangle_data.vertices[iFace * 3 + iVert]->get().normal;
+ }
+
fvNormOut[0] = v.x;
fvNormOut[1] = v.y;
fvNormOut[2] = v.z;
}
void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
- Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
- Vector2 v = varr[iFace * 3 + iVert]->get().uv;
+ TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+ Vector2 v;
+ if (triangle_data.indices.size() > 0) {
+ int index = triangle_data.indices[iFace * 3 + iVert]->get();
+ if (index < triangle_data.vertices.size()) {
+ v = triangle_data.vertices[index]->get().uv;
+ }
+ } else {
+ v = triangle_data.vertices[iFace * 3 + iVert]->get().uv;
+ }
+
fvTexcOut[0] = v.x;
fvTexcOut[1] = v.y;
- //fvTexcOut[1]=1.0-v.y;
}
void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
- Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
- Vertex *vtx = &varr[iFace * 3 + iVert]->get();
-
- vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
- vtx->binormal = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]);
-}
-
-void SurfaceTool::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) {
-
- Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
- Vertex &vtx = varr[iFace * 3 + iVert]->get();
+ TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+ Vertex *vtx = NULL;
+ if (triangle_data.indices.size() > 0) {
+ int index = triangle_data.indices[iFace * 3 + iVert]->get();
+ if (index < triangle_data.vertices.size()) {
+ vtx = &triangle_data.vertices[index]->get();
+ }
+ } else {
+ vtx = &triangle_data.vertices[iFace * 3 + iVert]->get();
+ }
- vtx.tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
- vtx.binormal = vtx.normal.cross(vtx.tangent) * fSign;
+ if (vtx != NULL) {
+ vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
+ vtx->binormal = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]);
+ }
}
void SurfaceTool::generate_tangents() {
@@ -823,10 +862,6 @@ void SurfaceTool::generate_tangents() {
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_TEX_UV));
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_NORMAL));
- bool indexed = index_array.size() > 0;
- if (indexed)
- deindex();
-
SMikkTSpaceInterface mkif;
mkif.m_getNormal = mikktGetNormal;
mkif.m_getNumFaces = mikktGetNumFaces;
@@ -839,24 +874,25 @@ void SurfaceTool::generate_tangents() {
SMikkTSpaceContext msc;
msc.m_pInterface = &mkif;
- Vector<List<Vertex>::Element *> vtx;
- vtx.resize(vertex_array.size());
+ TangentGenerationContextUserData triangle_data;
+ triangle_data.vertices.resize(vertex_array.size());
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
- vtx.write[idx++] = E;
+ triangle_data.vertices.write[idx++] = E;
E->get().binormal = Vector3();
E->get().tangent = Vector3();
}
- msc.m_pUserData = &vtx;
+ triangle_data.indices.resize(index_array.size());
+ idx = 0;
+ for (List<int>::Element *E = index_array.front(); E; E = E->next()) {
+ triangle_data.indices.write[idx++] = E;
+ }
+ msc.m_pUserData = &triangle_data;
bool res = genTangSpaceDefault(&msc);
ERR_FAIL_COND(!res);
format |= Mesh::ARRAY_FORMAT_TANGENT;
-
- if (indexed) {
- index();
- }
}
void SurfaceTool::generate_normals(bool p_flip) {
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 459d399380..cc8599e90a 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -90,7 +90,6 @@ private:
static void mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert);
static void mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert);
static void mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert);
- static void mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
const tbool bIsOrientationPreserving, const int iFace, const int iVert);