Merge pull request #29700 from clayjohn/cpuparticles_transform_bug

Fix CPU particles bug with local_coords and transform
This commit is contained in:
Rémi Verschelde 2019-06-16 10:49:30 +02:00 committed by GitHub
commit 9d3342545d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 14 deletions

View file

@ -86,7 +86,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;
@ -860,11 +862,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();
@ -886,7 +883,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) {
@ -1055,6 +1052,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) {

View file

@ -144,6 +144,8 @@ private:
int fixed_fps;
bool fractional_delta;
Transform2D inv_emission_transform;
DrawOrder draw_order;
Ref<Texture> texture;

View file

@ -915,11 +915,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();
@ -937,7 +932,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;
@ -955,7 +955,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) {
@ -1121,6 +1121,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) {
@ -1397,6 +1437,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);

View file

@ -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;