Example #1
0
 // a and b are not overlapping if they are seperated on any major axis
 bool TestAABBAABB(const AABB& a, const AABB& b)
 {
     if(a.Max().x < b.Min().x || a.Min().x > b.Max().x) return false;
     if(a.Max().z < b.Min().z || a.Min().z > b.Max().z) return false;
     if(a.Max().y < b.Min().y || a.Min().y > b.Max().y) return false;
     return true;
 }
Example #2
0
    bool IntersectRayAABB(const Ray& r, const AABB& a, float* out_tmin, float3* out_pos, float3* out_nor)
    {
        const float3& p = r.pos;
        const float3& d = r.direction;
        float tmin = -FLT_MAX;
        float tmax = FLT_MAX;
        float3 minNorm, maxNorm;
        
        // check vs. all three 'slabs' of the aabb
        for(int i = 0; i < 3; ++i)
        {
            if(abs(d[i]) < Epsilon) 
            {   // ray is parallel to slab, no hit if origin not within slab
                if(p[i] < a.Min()[i] || p[i] > a.Max()[i] )
                {
                    return false;
                }
            }
            else
            {
                // compute intersection t values of ray with near and far plane of slab
                float ood = 1.0f / d[i];
                float t1 = (a.Min()[i] - p[i]) * ood;
                float t2 = (a.Max()[i] - p[i]) * ood;
                tmin = maximize(tmin, minimize(t1, t2));
                tmax = minimize(tmax, maximize(t1, t2));

                // exit with no collision as soon as slab intersection becomes empty
                if(tmin > tmax) 
                {
                    return false;
                }
            }
        }
        
        if(tmax < 0.f)
        {
            // entire bounding box is behind us
            return false;
        }
        else if(tmin < 0.f)
        {
            // we are inside the bounding box
            *out_tmin = 0.f;
            *out_pos = p;
            *out_nor = normalize(a.GetCenter() - (*out_pos)); // use 'sphere' type normal calculation to approximate.
            return true;
        }
        else
        {
            // ray intersects all 3 slabs. return point and normal of intersection
            *out_tmin = tmin;
            *out_pos = p + d * tmin;
            *out_nor = normalize(a.GetCenter() - (*out_pos)); // use 'sphere' type normal calculation to approximate.
            return true;
        }
    }
Example #3
0
    AABB operator*(const Mat4& transform, const AABB& aabb)
    {
        const Vec4 newMin = transform * Vec4( aabb.Min(), 1.0f );
		const Vec4 newMax = transform * Vec4( aabb.Max(), 1.0f );

		return AABB( Vec3( newMin ), Vec3( newMax ) );
    }
Example #4
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);
}
Example #5
0
void LineRenderer::DrawAABB(const AABB& aabb, const float4& color)
{
    float3 min = aabb.Min();
    float3 max = aabb.Max(); 
    

    // render top quad    
    m_vertsPC.push_back(VertexPC(max,color));      
    m_vertsPC.push_back(VertexPC(float3(min.x,max.y,max.z),color));

    m_vertsPC.push_back(VertexPC(float3(min.x,max.y,max.z),color));
    m_vertsPC.push_back(VertexPC(float3(min.x,max.y,min.z),color));

    m_vertsPC.push_back(VertexPC(float3(min.x,max.y,min.z),color));
    m_vertsPC.push_back(VertexPC(float3(max.x,max.y,min.z),color));

    m_vertsPC.push_back(VertexPC(float3(max.x,max.y,min.z),color));
    m_vertsPC.push_back(VertexPC(max,color));

    // render bottom quad
    m_vertsPC.push_back(VertexPC(float3(max.x,min.y,max.z),color));      
    m_vertsPC.push_back(VertexPC(float3(min.x,min.y,max.z),color));

    m_vertsPC.push_back(VertexPC(float3(min.x,min.y,max.z),color));
    m_vertsPC.push_back(VertexPC(float3(min.x,min.y,min.z),color));

    m_vertsPC.push_back(VertexPC(float3(min.x,min.y,min.z),color));
    m_vertsPC.push_back(VertexPC(float3(max.x,min.y,min.z),color));

    m_vertsPC.push_back(VertexPC(float3(max.x,min.y,min.z),color));
    m_vertsPC.push_back(VertexPC(float3(max.x,min.y,max.z),color));

    // four legs
    m_vertsPC.push_back(VertexPC(max,color));  
    m_vertsPC.push_back(VertexPC(float3(max.x,min.y,max.z),color));      

    m_vertsPC.push_back(VertexPC(float3(min.x,max.y,max.z),color));
    m_vertsPC.push_back(VertexPC(float3(min.x,min.y,max.z),color));

    m_vertsPC.push_back(VertexPC(float3(min.x,max.y,min.z),color));
    m_vertsPC.push_back(VertexPC(float3(min.x,min.y,min.z),color));

    m_vertsPC.push_back(VertexPC(float3(max.x,max.y,min.z),color));
    m_vertsPC.push_back(VertexPC(float3(max.x,min.y,min.z),color));

}
Example #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);
}