fix CPU particles bug with local_coords and transform
(cherry picked from commit 52696e98b4
)
This commit is contained in:
parent
abf19bdab2
commit
3689ac6c6b
|
@ -84,7 +84,9 @@ void CPUParticles2D::set_randomness_ratio(float p_ratio) {
|
||||||
void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
|
void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
|
||||||
|
|
||||||
local_coords = p_enable;
|
local_coords = p_enable;
|
||||||
|
set_notify_transform(!p_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUParticles2D::set_speed_scale(float p_scale) {
|
void CPUParticles2D::set_speed_scale(float p_scale) {
|
||||||
|
|
||||||
speed_scale = p_scale;
|
speed_scale = p_scale;
|
||||||
|
@ -864,11 +866,6 @@ void CPUParticles2D::_update_particle_data_buffer() {
|
||||||
PoolVector<Particle>::Read r = particles.read();
|
PoolVector<Particle>::Read r = particles.read();
|
||||||
float *ptr = w.ptr();
|
float *ptr = w.ptr();
|
||||||
|
|
||||||
Transform2D un_transform;
|
|
||||||
if (!local_coords) {
|
|
||||||
un_transform = get_global_transform().affine_inverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (draw_order != DRAW_ORDER_INDEX) {
|
if (draw_order != DRAW_ORDER_INDEX) {
|
||||||
ow = particle_order.write();
|
ow = particle_order.write();
|
||||||
order = ow.ptr();
|
order = ow.ptr();
|
||||||
|
@ -890,7 +887,7 @@ void CPUParticles2D::_update_particle_data_buffer() {
|
||||||
Transform2D t = r[idx].transform;
|
Transform2D t = r[idx].transform;
|
||||||
|
|
||||||
if (!local_coords) {
|
if (!local_coords) {
|
||||||
t = un_transform * t;
|
t = inv_emission_transform * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r[idx].active) {
|
if (r[idx].active) {
|
||||||
|
@ -1059,6 +1056,42 @@ void CPUParticles2D::_notification(int p_what) {
|
||||||
|
|
||||||
_update_particle_data_buffer();
|
_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) {
|
void CPUParticles2D::convert_from_particles(Node *p_particles) {
|
||||||
|
|
|
@ -142,6 +142,8 @@ private:
|
||||||
int fixed_fps;
|
int fixed_fps;
|
||||||
bool fractional_delta;
|
bool fractional_delta;
|
||||||
|
|
||||||
|
Transform2D inv_emission_transform;
|
||||||
|
|
||||||
DrawOrder draw_order;
|
DrawOrder draw_order;
|
||||||
|
|
||||||
Ref<Texture> texture;
|
Ref<Texture> texture;
|
||||||
|
|
|
@ -909,11 +909,6 @@ void CPUParticles::_update_particle_data_buffer() {
|
||||||
PoolVector<Particle>::Read r = particles.read();
|
PoolVector<Particle>::Read r = particles.read();
|
||||||
float *ptr = w.ptr();
|
float *ptr = w.ptr();
|
||||||
|
|
||||||
Transform un_transform;
|
|
||||||
if (!local_coords) {
|
|
||||||
un_transform = get_global_transform().affine_inverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (draw_order != DRAW_ORDER_INDEX) {
|
if (draw_order != DRAW_ORDER_INDEX) {
|
||||||
ow = particle_order.write();
|
ow = particle_order.write();
|
||||||
order = ow.ptr();
|
order = ow.ptr();
|
||||||
|
@ -931,7 +926,12 @@ void CPUParticles::_update_particle_data_buffer() {
|
||||||
Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
|
Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
|
||||||
|
|
||||||
if (local_coords) {
|
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;
|
SortArray<int, SortAxis> sorter;
|
||||||
|
@ -949,7 +949,7 @@ void CPUParticles::_update_particle_data_buffer() {
|
||||||
Transform t = r[idx].transform;
|
Transform t = r[idx].transform;
|
||||||
|
|
||||||
if (!local_coords) {
|
if (!local_coords) {
|
||||||
t = un_transform * t;
|
t = inv_emission_transform * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r[idx].active) {
|
if (r[idx].active) {
|
||||||
|
@ -1114,6 +1114,46 @@ void CPUParticles::_notification(int p_what) {
|
||||||
_update_particle_data_buffer();
|
_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) {
|
void CPUParticles::convert_from_particles(Node *p_particles) {
|
||||||
|
@ -1391,6 +1431,8 @@ CPUParticles::CPUParticles() {
|
||||||
cycle = 0;
|
cycle = 0;
|
||||||
redraw = false;
|
redraw = false;
|
||||||
|
|
||||||
|
set_notify_transform(true);
|
||||||
|
|
||||||
multimesh = VisualServer::get_singleton()->multimesh_create();
|
multimesh = VisualServer::get_singleton()->multimesh_create();
|
||||||
set_base(multimesh);
|
set_base(multimesh);
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ private:
|
||||||
const Particle *particles;
|
const Particle *particles;
|
||||||
|
|
||||||
bool operator()(int p_a, int p_b) const {
|
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;
|
int fixed_fps;
|
||||||
bool fractional_delta;
|
bool fractional_delta;
|
||||||
|
|
||||||
|
Transform inv_emission_transform;
|
||||||
|
|
||||||
volatile bool can_update;
|
volatile bool can_update;
|
||||||
|
|
||||||
DrawOrder draw_order;
|
DrawOrder draw_order;
|
||||||
|
|
Loading…
Reference in New Issue