Beispiel #1
0
    void GameObjectGroup::Update(const FrameTime& fr, UpdateTypeEnum updateType)
    {
        bool boundDirty = m_boundsDirty;
        super::Update(fr,updateType);
        m_boundsDirty = boundDirty;
        for( auto it = m_children.begin(); it != m_children.end(); ++it)
        {
            (*it)->Update(fr,updateType);
        }


        // Update bounds
        if(m_boundsDirty)
        {            
            bool usechildbounds = false;
            AABB childbounds; // default ctor will set initial value of min and max.
            // merge bounds for the the visibile children.
            for (auto it = m_children.begin(); it != m_children.end(); ++it)
            {
                if( (*it)->IsVisible())
                {                    
                    AABB local = (*it)->GetLocalBounds();
                    local.Transform((*it)->GetTransform());
                    childbounds.Extend( local );
                    usechildbounds = true;
                }
            }
                 
            // set local bounds 
            m_localBounds = usechildbounds ? childbounds : AABB(float3(-0.5f,-0.5f,-0.5f), float3(0.5f,0.5f,0.5f));
            UpdateWorldAABB();                      
        }
    }
Beispiel #2
0
// ------------------------------------------------------------------------------------------------
void Model::UpdateBounds()
{
    assert(m_constructed==true);
    const GeometryDict& geos = Geometries();
    if(geos.size()==0)
    {
        return;
    }

    float3 min = float3(FLT_MAX, FLT_MAX, FLT_MAX);
    float3 max = float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
    const NodeDict& nodes = Nodes();
    for(auto nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
    {
        Node* node = nodeIt->second;
        for(auto geoIt = node->geometries.begin(); geoIt != node->geometries.end(); ++geoIt)
        {
            Geometry * geo = (*geoIt);
            AABB bbox = geo->mesh->bounds;
            bbox.Transform(m_nodeTransforms[node->index]);
            min = minimize(min, bbox.Min());
            max = maximize(max, bbox.Max());
        }
    }
    // note: min & max already transformed by entire object world matrix
    m_bounds = AABB(min, max);
}
Beispiel #3
0
OBB operator *(const Quat &transform, const AABB &aabb)
{
	return aabb.Transform(transform);
}
Beispiel #4
0
OBB operator *(const float4x4 &transform, const AABB &aabb)
{
	return aabb.Transform(transform);
}
Beispiel #5
0
void CurveGob::Update(const FrameTime& fr, UpdateTypeEnum updateType)
{
    bool boundDirty = m_boundsDirty;
    super::Update(fr,updateType);
    m_boundsDirty = boundDirty;

    if(!m_boundsDirty) return;

    m_mesh.pos.clear();    
    if(m_needsRebuild)
    {        
        SAFE_DELETE(m_mesh.vertexBuffer);
    }

    if(m_points.size()<2)
    {
        m_localBounds = AABB(float3(-0.5f,-0.5f,-0.5f), float3(0.5f,0.5f,0.5f));
        UpdateWorldAABB();       
        return;
    }

    // compute local bounds.
    m_localBounds =  m_points[0]->GetLocalBounds();
    m_localBounds.Transform(m_points[0]->GetTransform());
    for( auto it = m_points.begin(); it != m_points.end(); ++it)
    {
        (*it)->Update(fr,updateType);
        AABB local = (*it)->GetLocalBounds();
        local.Transform((*it)->GetTransform());
        m_localBounds.Extend(local);
    }

    // compute world bound.
    float3 min,max;
    min = m_points[0]->GetBounds().Min();
    max = m_points[0]->GetBounds().Max();
    for( auto it = m_points.begin(); it != m_points.end(); ++it)
    {
        min = minimize(min, (*it)->GetBounds().Min());
        max = maximize(max, (*it)->GetBounds().Max());
    }
    m_bounds = AABB(min,max);                    
    m_boundsDirty = false;
    std::vector<float3> verts;
    switch(m_type)
    {
    default:
        Logger::Log(OutputMessageType::Error, "Invalid curve type, '%d'\n", m_type);
        // fall through and just pretend it is Linear

    case Linear:
        {// add all the normal control point positions
            
            for(auto it = m_points.begin(); it != m_points.end(); ++it)
            {
                float3 vert = float3(&(*it)->GetTransform().M41);
                verts.push_back(vert);
            }
            if(m_closed)
            {
                verts.push_back(verts[0]);
            }
            break;
        }
    case CatmullRom:
        {          
            std::vector<float3> points;
            //// since catmull-rom interpolation requires additional points, we want to calculate
            //// to 'fake' points to be the endpoints. That way our line will exists for all the
            //// actual control points.
            size_t size = m_points.size();
            if(m_closed)
            {
                // add the last point before others for consistent interpolation
                points.push_back(float3(&m_points[size-1]->GetTransform().M41));
            }
            else
            {
                // add an extra point in front of the 1st control point for interpolation
                float3 p1(&m_points[0]->GetTransform().M41);
                float3 p2(&m_points[1]->GetTransform().M41);
                float3 delta = p1 - p2; // from p2 to p1
                points.push_back(p1 + delta);
            }

            // add all normal control point positions
            for(auto it = m_points.begin(); it != m_points.end(); ++it)
            {
                points.push_back(float3(&(*it)->GetTransform().M41));
            }

            if(m_closed)
            {
                // add first and second points for consistent interpolation
                points.push_back(&m_points[0]->GetTransform().M41);
                points.push_back(&m_points[1]->GetTransform().M41);
            }
            else
            {
                // add an extra point in after of the last control point for interpolation
                float3 p1 = points[size-1];
                float3 p2 = points[size-2];
                float3 delta = p1 - p2; // from p2 to p1
                points.push_back(p1 + delta);
            }

            // Interpolate                        
            size_t sz = points.size() - 2;               
            for(unsigned int index = 1; index < sz; index++)
            {       
                float3 p0 = points[index-1];
                float3 p1 = points[index];
                float3 p2 = points[index+1];
                float3 p3 = points[index+2];

                for(int i = 0; i < m_steps; ++i)
                {                    
                    float s = (float)i / (float)m_steps;                    
                    verts.push_back(Vec3CatmullRom(p0,p1,p2,p3,s));
                }                
            }    
            verts.push_back(points[sz]);           
            break;
        }
    case Bezier:
        {
            std::vector<float3> points;
             // add all normal control point positions
            for(auto it = m_points.begin(); it != m_points.end(); ++it)
            {
                points.push_back(float3(&(*it)->GetTransform().M41));
            }

            BezierSpline spline(&points[0],(int)points.size(),m_closed);

            for(int i = 0;  i < spline.CurveCount(); i++)
            {
                const BezierCurve& curve = spline.GetCurveAt(i);
                for(int k = 0; k < m_steps; k++)
                {
                    float s = (float)k / (float)m_steps;
                    verts.push_back(curve.Eval(s));                                    
                }
            }
            // Handle last point
            if (m_closed && m_points.size() > 2)
                verts.push_back(points[0]);
            else 
                verts.push_back(points[points.size()-1]);
            break;        
        }
    }
    
    for(auto it = verts.begin(); it != verts.end(); it++)
    {
        m_mesh.pos.push_back(*it);
    }
    m_mesh.ComputeBound();
    if(m_needsRebuild)
    {                       
        m_mesh.vertexBuffer = GpuResourceFactory::CreateVertexBuffer(&verts[0], VertexFormat::VF_P, (uint32_t)verts.size(), BufferUsage::DYNAMIC);
    }
    else
    {
        ID3D11DeviceContext* context = gD3D11->GetImmediateContext();
        assert(m_mesh.vertexBuffer != NULL);        
        m_mesh.vertexBuffer->Update(context,&verts[0],(uint32_t)verts.size());
    }    
    
    m_needsRebuild = false;    
}
Beispiel #6
0
//---------------------------------------------------------------------------
void ShadowMaps::UpdateLightCamera( ID3D11DeviceContext* dc, const DirLight* light, const AABB& renderedArea )
{
    float3 worldUp(0,1,0);
    float3 lightDir = normalize(light->dir);

    // compute ligtcam params.
    float dt = dot(-lightDir, worldUp);
    float3 center = renderedArea.GetCenter();
    float dim = length(renderedArea.Max() - renderedArea.Min());
    float radi = dim * 0.5f;

    float3 camPos = center - (radi * lightDir);
    float3 up;
    float3 right;

    if ((dt + Epsilon) >= 1)
    {
        up = float3(0, 0, -1);
        right = float3(1, 0, 0);

    }
    else
    {
        right = normalize(cross(lightDir, worldUp));
        up = normalize(cross(right, lightDir));
        right = cross(lightDir, worldUp);
        up = cross(right, lightDir);
    }


    // create view matrix from right, up and look, and position.
     float rp = -dot(right, camPos);
     float upp = -dot(up, camPos);
     float zp = dot(lightDir, camPos);
     Matrix view(
                right.x, up.x, -lightDir.x, 0.0f,
                right.y, up.y, -lightDir.y, 0.0f,
                right.z, up.z, -lightDir.z, 0.0f,
                rp, upp, zp, 1.0f);

    // compute the width, height, near, far by transforming the AABB into view space.
    AABB lbounds = renderedArea;
    lbounds.Transform(view);
    float3 vmin = lbounds.Min();
    float3 vmax = lbounds.Max();
    float width = vmax.x - vmin.x;
    float height = vmax.y - vmin.y;
    float nearz = 0.0f;
    float farz = dim;

    Matrix proj = Matrix::CreateOrthographic(width,height, nearz, farz);
    //Matrix proj = Matrix::CreateOrthographicOffCenter(vmin.x, vmax.x, vmin.y, vmax.y, nearz, farz);
    m_lightCamera.SetViewProj(view, proj);

    // update cb        
    m_cbShadow.Data.texelSize  = ( 1.0f / MapSize() );        

    // udpate constant buffer using lightcamera.
    // transform coords from NDC space to texture space.
    float4x4 ndcToTexSpace(  0.5f,  0.0f, 0.0f, 0.0f,
                             0.0f, -0.5f, 0.0f, 0.0f,
                             0.0f,  0.0f, 1.0f, 0.0f,
                             0.5f,  0.5f, 0.0f, 1.0f);
                                 
    float4x4 shadowViewProjection = (m_lightCamera.View() * m_lightCamera.Proj()) * ndcToTexSpace;
    Matrix::Transpose(shadowViewProjection, m_cbShadow.Data.xform);    
    m_cbShadow.Update(dc);
}