コード例 #1
0
void BuildCylinder(   
        core::array<video::S3DVertex>& vertexArray,
        core::array<u16>& indexArray,
        core::aabbox3d<f32>& boundingBox,
        
        f32 height,
        f32 startRadius,
        f32 endRadius,
        s32 radialSegments,
        
        const core::matrix4& transform,
        
        f32 startTCoordY = 0.0f,
        f32 endTCoordY = 1.0f,
        video::SColor startColor = video::SColor(255,255,255,255),
        video::SColor endColor = video::SColor(255,255,255,255) )
{
    u16 vertexIndex = vertexArray.size();
    
    s32 radialVertices = radialSegments + 1; // We want one additional vertex to make the texture wraps correctly
    
    // Place bottom cap
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df pos;
        core::vector3df normal = dir;

        pos = dir * startRadius;
        
        // Place bottom vertex
        transform.transformVect( pos );
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = startTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            startColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint( pos );
    }
    
    // Place top cap and indices
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df normal = dir;
        core::vector3df pos = dir * endRadius;
        pos.Y = height;
        
        transform.transformVect( pos ); 
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = endTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            endColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint(pos);
        
        // Add indices
        if ( i != radialVertices-1 )
        {
            s32 i2 = (i+1)%radialVertices;
            // Place the indices
            indexArray.push_back ( vertexIndex + i );
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + i2 );
            
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + radialVertices + i2 );
            indexArray.push_back ( vertexIndex + i2 );
        }
    }
}
コード例 #2
0
ファイル: stk_particle.cpp プロジェクト: devnexen/stk-code
// ----------------------------------------------------------------------------
void STKParticle::stimulateNormal(float dt, unsigned int active_count,
                                  std::vector<CPUParticle>* out)
{
    const core::matrix4 cur_matrix = AbsoluteTransformation;
    core::vector3df previous_frame_position, current_frame_position,
        previous_frame_direction, current_frame_direction;
    for (unsigned i = 0; i < m_max_count; i++)
    {
        core::vector3df new_particle_position;
        core::vector3df new_particle_direction;
        float new_size = 0.0f;
        float new_lifetime = 0.0f;

        const core::vector3df particle_position =
            m_particles_generating[i].m_position;
        const float lifetime = m_particles_generating[i].m_lifetime;
        const core::vector3df particle_direction =
            m_particles_generating[i].m_direction;
        const float size = m_particles_generating[i].m_size;

        const core::vector3df particle_position_initial =
            m_initial_particles[i].m_position;
        const float lifetime_initial = m_initial_particles[i].m_lifetime;
        const core::vector3df particle_direction_initial =
            m_initial_particles[i].m_direction;
        const float size_initial = m_initial_particles[i].m_size;

        float updated_lifetime = lifetime + (dt / lifetime_initial);
        if (updated_lifetime > 1.0f)
        {
            if (i < active_count)
            {
                float dt_from_last_frame =
                    glslFract(updated_lifetime) * lifetime_initial;
                float coeff = dt_from_last_frame / dt;

                m_previous_frame_matrix.transformVect(previous_frame_position,
                    particle_position_initial);
                cur_matrix.transformVect(current_frame_position,
                    particle_position_initial);

                core::vector3df updated_position = previous_frame_position
                    .getInterpolated(current_frame_position, coeff);

                m_previous_frame_matrix.rotateVect(previous_frame_direction,
                    particle_direction_initial);
                cur_matrix.rotateVect(current_frame_direction,
                    particle_direction_initial);

                core::vector3df updated_direction = previous_frame_direction
                    .getInterpolated(current_frame_direction, coeff);
                // + (current_frame_position - previous_frame_position) / dt;

                // To be accurate, emitter speed should be added.
                // But the simple formula
                // ( (current_frame_position - previous_frame_position) / dt )
                // with a constant speed between 2 frames creates visual
                // artifacts when the framerate is low, and a more accurate
                // formula would need more complex computations.

                new_particle_position = updated_position + dt_from_last_frame *
                    updated_direction;
                new_particle_direction = updated_direction;

                new_lifetime = glslFract(updated_lifetime);
                new_size = glslMix(size_initial,
                    size_initial * m_size_increase_factor,
                    glslFract(updated_lifetime));
            }
            else
            {
                new_lifetime = glslFract(updated_lifetime);
                new_size = 0.0f;
            }
        }
        else
        {
            new_particle_position = particle_position +
                particle_direction * dt;
            new_particle_direction = particle_direction;
            new_lifetime = updated_lifetime;
            new_size = (size == 0.0f) ? 0.0f :
                glslMix(size_initial, size_initial * m_size_increase_factor,
                updated_lifetime);
        }
        m_particles_generating[i].m_position = new_particle_position;
        m_particles_generating[i].m_lifetime = new_lifetime;
        m_particles_generating[i].m_direction = new_particle_direction;
        m_particles_generating[i].m_size = new_size;
        if (out != NULL)
        {
            if (m_flips || new_size != 0.0f)
            {
                if (new_size != 0.0f)
                {
                    Buffer->BoundingBox.addInternalPoint
                        (new_particle_position);
                }
                out->emplace_back(new_particle_position, m_color_from,
                    m_color_to, new_lifetime, new_size);
            }
        }
    }
}   // stimulateNormal