void Vertex::Rotate(const Vector3& centre, Vector3 amount) { //Begining of Glorious Hack! //Apply changes for rotation around Z if (amount.z != 0.0f) { Vector2 rotVect(x - centre.x, y - centre.y); rotVect.ToPolar(); rotVect.x += amount.z; rotVect.ToCartesian(); x = centre.x + rotVect.x; y = centre.y + rotVect.y; } //Apply changes for rotation around Y if (amount.y != 0.0f) { Vector2 rotVect(x - centre.x, z - centre.z); rotVect.ToPolar(); rotVect.x += amount.y; rotVect.ToCartesian(); x = centre.x + rotVect.x; z = centre.z + rotVect.y; //which is actually the vertex's Z coordinate } //Apply changes for rotation around X if (amount.x != 0.0f) { Vector2 rotVect(z - centre.z, y - centre.y); rotVect.ToPolar(); rotVect.x += amount.x; rotVect.ToCartesian(); z = centre.z + rotVect.x; y = centre.y + rotVect.y; } //End of Glorious Hack! }
void ParticleEmitter3D::PrepareEmitterParameters(Particle * particle, float32 velocity, int32 emitIndex) { Vector3 tempPosition = Vector3(); Matrix4 * worldTransformPtr = GetWorldTransformPtr(); if(worldTransformPtr) { tempPosition = worldTransformPtr->GetTranslationVector(); } //Vector3 tempPosition = particlesFollow ? Vector3() : position; if (emitterType == EMITTER_POINT) { particle->position = tempPosition; } else if (emitterType == EMITTER_LINE) { // TODO: add emitter angle support float32 rand05 = (float32)Random::Instance()->RandFloat() - 0.5f; // [-0.5f, 0.5f] Vector3 lineDirection(0, 0, 0); if(size) lineDirection = size->GetValue(time)*rand05; particle->position = tempPosition + lineDirection; } else if (emitterType == EMITTER_RECT) { // TODO: add emitter angle support float32 rand05_x = (float32)Random::Instance()->RandFloat() - 0.5f; // [-0.5f, 0.5f] float32 rand05_y = (float32)Random::Instance()->RandFloat() - 0.5f; // [-0.5f, 0.5f] float32 rand05_z = (float32)Random::Instance()->RandFloat() - 0.5f; // [-0.5f, 0.5f] Vector3 lineDirection(0, 0, 0); if(size) lineDirection = Vector3(size->GetValue(time).x * rand05_x, size->GetValue(time).y * rand05_y, size->GetValue(time).z * rand05_z); particle->position = tempPosition + lineDirection; } else if (emitterType == EMITTER_ONCIRCLE) { // here just set particle position particle->position = tempPosition; } Vector3 vel = Vector3(1.0f, 0.0f, 0.0f); if(emissionVector) { vel = emissionVector->GetValue(0); vel = vel*rotationMatrix; } Vector3 rotVect(0, 0, 1); float32 phi = PI*2*(float32)Random::Instance()->RandFloat(); if(vel.x != 0) { rotVect.y = sinf(phi); rotVect.z = cosf(phi); rotVect.x = - rotVect.y*vel.y/vel.x - rotVect.z*vel.z/vel.x; } else if(vel.y != 0) { rotVect.x = cosf(phi); rotVect.z = sinf(phi); rotVect.y = - rotVect.z*vel.z/vel.y; } else if(vel.z != 0) { rotVect.x = cosf(phi); rotVect.y = sinf(phi); rotVect.z = 0; } rotVect.Normalize(); float32 range = 0; if(emissionRange) range = DegToRad(emissionRange->GetValue(time) + angle); float32 rand05 = (float32)Random::Instance()->RandFloat() - 0.5f; Vector3 q_v(rotVect*sinf(range*rand05/2)); float32 q_w = cosf(range*rand05/2); Vector3 q1_v(q_v); float32 q1_w = -q_w; q1_v /= (q_v.SquareLength() + q_w*q_w); q1_w /= (q_v.SquareLength() + q_w*q_w); Vector3 v_v(vel); Vector3 qv_v = q_v.CrossProduct(v_v) + q_w*v_v; float32 qv_w = - q_v.DotProduct(v_v); Vector3 qvq1_v = qv_v.CrossProduct(q1_v) + qv_w*q1_v + q1_w*qv_v; Vector3 speed = qvq1_v * velocity; particle->speed = speed.Length(); particle->direction = speed/particle->speed; if (particle->direction.x <= EPSILON && particle->direction.x >= -EPSILON) particle->direction.x = 0.f; if (particle->direction.y <= EPSILON && particle->direction.y >= -EPSILON) particle->direction.y = 0.f; if (particle->direction.z <= EPSILON && particle->direction.z >= -EPSILON) particle->direction.z = 0.f; if (emitterType == EMITTER_ONCIRCLE) { qvq1_v.Normalize(); if(radius) particle->position += qvq1_v * radius->GetValue(time); } particle->angle = atanf(particle->direction.z/particle->direction.x); if(worldTransformPtr) { Matrix4 newTransform = *worldTransformPtr; newTransform._30 = newTransform._31 = newTransform._32 = 0; particle->direction = particle->direction*newTransform; } }
void ParticleEmitter3D::PrepareEmitterParametersGeneric(Particle * particle, float32 velocity, int32 emitIndex, const Vector3& tempPosition, const Matrix3& rotationMatrix) { Vector3 vel = Vector3(1.0f, 0.0f, 0.0f); if(emissionVector) { // Yuri Coder, 2013/04/12. Need to invert the directions in the emission vector, since // their coordinates are in the opposite directions for the Particles Editor. vel = emissionVector->GetValue(0) * -1.0f; } Vector3 rotVect(0, 0, 1); float32 phi = PI*2*(float32)Random::Instance()->RandFloat(); if(vel.x != 0) { rotVect.y = sinf(phi); rotVect.z = cosf(phi); rotVect.x = - rotVect.y*vel.y/vel.x - rotVect.z*vel.z/vel.x; } else if(vel.y != 0) { rotVect.x = cosf(phi); rotVect.z = sinf(phi); rotVect.y = - rotVect.z*vel.z/vel.y; } else if(vel.z != 0) { rotVect.x = cosf(phi); rotVect.y = sinf(phi); rotVect.z = 0; } rotVect.Normalize(); float32 range = 0; if(emissionRange) range = DegToRad(emissionRange->GetValue(time) + angle); float32 rand05 = (float32)Random::Instance()->RandFloat() - 0.5f; Vector3 q_v(rotVect*sinf(range*rand05/2)); float32 q_w = cosf(range*rand05/2); Vector3 q1_v(q_v); float32 q1_w = -q_w; q1_v /= (q_v.SquareLength() + q_w*q_w); q1_w /= (q_v.SquareLength() + q_w*q_w); Vector3 v_v(vel); Vector3 qv_v = q_v.CrossProduct(v_v) + q_w*v_v; float32 qv_w = - q_v.DotProduct(v_v); Vector3 qvq1_v = qv_v.CrossProduct(q1_v) + qv_w*q1_v + q1_w*qv_v; particle->speed = qvq1_v * velocity; // Yuri Coder, 2013/03/26. After discussion with Ivan it appears this angle // calculation is incorrect. TODO: return to this code later on. //particle->angle = atanf(particle->direction.z/particle->direction.x); }