summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorclayjohn <claynjohn@gmail.com>2019-06-14 13:22:19 -0700
committerclayjohn <claynjohn@gmail.com>2019-06-14 13:22:19 -0700
commit52696e98b4dbba07ffb642bf675798acf312ae92 (patch)
tree7e7a53f40effe7a72494cbffa08c2d1014d6b833 /scene
parent30e8b53c380a7bc88fbea768e31bc6b64f27f0ef (diff)
fix CPU particles bug with local_coords and transform
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/cpu_particles_2d.cpp45
-rw-r--r--scene/2d/cpu_particles_2d.h2
-rw-r--r--scene/3d/cpu_particles.cpp56
-rw-r--r--scene/3d/cpu_particles.h4
4 files changed, 93 insertions, 14 deletions
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index ff27e0a29a..08304e1e52 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -85,7 +85,9 @@ void CPUParticles2D::set_randomness_ratio(float p_ratio) {
void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
local_coords = p_enable;
+ set_notify_transform(!p_enable);
}
+
void CPUParticles2D::set_speed_scale(float p_scale) {
speed_scale = p_scale;
@@ -865,11 +867,6 @@ void CPUParticles2D::_update_particle_data_buffer() {
PoolVector<Particle>::Read r = particles.read();
float *ptr = w.ptr();
- Transform2D un_transform;
- if (!local_coords) {
- un_transform = get_global_transform().affine_inverse();
- }
-
if (draw_order != DRAW_ORDER_INDEX) {
ow = particle_order.write();
order = ow.ptr();
@@ -891,7 +888,7 @@ void CPUParticles2D::_update_particle_data_buffer() {
Transform2D t = r[idx].transform;
if (!local_coords) {
- t = un_transform * t;
+ t = inv_emission_transform * t;
}
if (r[idx].active) {
@@ -1060,6 +1057,42 @@ void CPUParticles2D::_notification(int p_what) {
_update_particle_data_buffer();
}
+
+ if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
+
+ inv_emission_transform = get_global_transform().affine_inverse();
+
+ if (!local_coords) {
+
+ int pc = particles.size();
+
+ PoolVector<float>::Write w = particle_data.write();
+ PoolVector<Particle>::Read r = particles.read();
+ float *ptr = w.ptr();
+
+ for (int i = 0; i < pc; i++) {
+
+ Transform2D t = inv_emission_transform * r[i].transform;
+
+ if (r[i].active) {
+
+ ptr[0] = t.elements[0][0];
+ ptr[1] = t.elements[1][0];
+ ptr[2] = 0;
+ ptr[3] = t.elements[2][0];
+ ptr[4] = t.elements[0][1];
+ ptr[5] = t.elements[1][1];
+ ptr[6] = 0;
+ ptr[7] = t.elements[2][1];
+
+ } else {
+ zeromem(ptr, sizeof(float) * 8);
+ }
+
+ ptr += 13;
+ }
+ }
+ }
}
void CPUParticles2D::convert_from_particles(Node *p_particles) {
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 81343a4604..ccba576cb1 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -142,6 +142,8 @@ private:
int fixed_fps;
bool fractional_delta;
+ Transform2D inv_emission_transform;
+
DrawOrder draw_order;
Ref<Texture> texture;
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index 138c446fea..bc06e1a96e 100644
--- a/scene/3d/cpu_particles.cpp
+++ b/scene/3d/cpu_particles.cpp
@@ -910,11 +910,6 @@ void CPUParticles::_update_particle_data_buffer() {
PoolVector<Particle>::Read r = particles.read();
float *ptr = w.ptr();
- Transform un_transform;
- if (!local_coords) {
- un_transform = get_global_transform().affine_inverse();
- }
-
if (draw_order != DRAW_ORDER_INDEX) {
ow = particle_order.write();
order = ow.ptr();
@@ -932,7 +927,12 @@ void CPUParticles::_update_particle_data_buffer() {
Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
if (local_coords) {
- dir = un_transform.basis.xform(dir).normalized();
+
+ // will look different from Particles in editor as this is based on the camera in the scenetree
+ // and not the editor camera
+ dir = inv_emission_transform.xform(dir).normalized();
+ } else {
+ dir = dir.normalized();
}
SortArray<int, SortAxis> sorter;
@@ -950,7 +950,7 @@ void CPUParticles::_update_particle_data_buffer() {
Transform t = r[idx].transform;
if (!local_coords) {
- t = un_transform * t;
+ t = inv_emission_transform * t;
}
if (r[idx].active) {
@@ -1116,6 +1116,46 @@ void CPUParticles::_notification(int p_what) {
_update_particle_data_buffer();
}
}
+
+ if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
+
+ inv_emission_transform = get_global_transform().affine_inverse();
+
+ if (!local_coords) {
+
+ int pc = particles.size();
+
+ PoolVector<float>::Write w = particle_data.write();
+ PoolVector<Particle>::Read r = particles.read();
+ float *ptr = w.ptr();
+
+ for (int i = 0; i < pc; i++) {
+
+ Transform t = inv_emission_transform * r[i].transform;
+
+ if (r[i].active) {
+ ptr[0] = t.basis.elements[0][0];
+ ptr[1] = t.basis.elements[0][1];
+ ptr[2] = t.basis.elements[0][2];
+ ptr[3] = t.origin.x;
+ ptr[4] = t.basis.elements[1][0];
+ ptr[5] = t.basis.elements[1][1];
+ ptr[6] = t.basis.elements[1][2];
+ ptr[7] = t.origin.y;
+ ptr[8] = t.basis.elements[2][0];
+ ptr[9] = t.basis.elements[2][1];
+ ptr[10] = t.basis.elements[2][2];
+ ptr[11] = t.origin.z;
+ } else {
+ zeromem(ptr, sizeof(float) * 12);
+ }
+
+ ptr += 17;
+ }
+
+ can_update = true;
+ }
+ }
}
void CPUParticles::convert_from_particles(Node *p_particles) {
@@ -1393,6 +1433,8 @@ CPUParticles::CPUParticles() {
cycle = 0;
redraw = false;
+ set_notify_transform(true);
+
multimesh = VisualServer::get_singleton()->multimesh_create();
VisualServer::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
set_base(multimesh);
diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h
index b863a3cb3f..6784d49e92 100644
--- a/scene/3d/cpu_particles.h
+++ b/scene/3d/cpu_particles.h
@@ -116,7 +116,7 @@ private:
const Particle *particles;
bool operator()(int p_a, int p_b) const {
- return particles[p_a].time < particles[p_b].time;
+ return particles[p_a].time > particles[p_b].time;
}
};
@@ -142,6 +142,8 @@ private:
int fixed_fps;
bool fractional_delta;
+ Transform inv_emission_transform;
+
volatile bool can_update;
DrawOrder draw_order;