예제 #1
0
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);
}