bool StaticModelGroup::DrawOcclusion(OcclusionBuffer* buffer)
{
    // Make sure instance transforms are up-to-date
    GetWorldBoundingBox();
    
    for (unsigned i = 0; i < numWorldTransforms_; ++i)
    {
        for (unsigned j = 0; j < batches_.Size(); ++j)
        {
            Geometry* geometry = GetLodGeometry(j, occlusionLodLevel_);
            if (!geometry)
                continue;
            
            // Check that the material is suitable for occlusion (default material always is) and set culling mode
            Material* material = batches_[j].material_;
            if (material)
            {
                if (!material->GetOcclusion())
                    continue;
                buffer->SetCullMode(material->GetCullMode());
            }
            else
                buffer->SetCullMode(CULL_CCW);
            
            const unsigned char* vertexData;
            unsigned vertexSize;
            const unsigned char* indexData;
            unsigned indexSize;
            unsigned elementMask;
            
            geometry->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
            // Check for valid geometry data
            if (!vertexData || !indexData)
                continue;
            
            unsigned indexStart = geometry->GetIndexStart();
            unsigned indexCount = geometry->GetIndexCount();
            
            // Draw and check for running out of triangles
            if (!buffer->Draw(worldTransforms_[i], vertexData, vertexSize, indexData, indexSize, indexStart, indexCount))
                return false;
        }
    }
    
    return true;
}
bool CustomGeometry::DrawOcclusion(OcclusionBuffer* buffer)
{
    bool success = true;

    for (unsigned i = 0; i < batches_.Size(); ++i)
    {
        Geometry* geometry = GetLodGeometry(i, 0);
        if (!geometry)
            continue;

        // Check that the material is suitable for occlusion (default material always is) and set culling mode
        Material* material = batches_[i].material_;
        if (material)
        {
            if (!material->GetOcclusion())
                continue;
            buffer->SetCullMode(material->GetCullMode());
        }
        else
            buffer->SetCullMode(CULL_CCW);

        const unsigned char* vertexData;
        unsigned vertexSize;
        const unsigned char* indexData;
        unsigned indexSize;
        const PODVector<VertexElement>* elements;

        geometry->GetRawData(vertexData, vertexSize, indexData, indexSize, elements);
        // Check for valid geometry data
        if (!vertexData || !elements || VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3, SEM_POSITION) != 0)
            continue;

        // Draw and check for running out of triangles
        success = buffer->AddTriangles(node_->GetWorldTransform(), vertexData, vertexSize, geometry->GetVertexStart(),
            geometry->GetVertexCount());

        if (!success)
            break;
    }

    return success;
}
Exemple #3
0
ConvexData::ConvexData(CustomGeometry* custom)
{
    PODVector<Vector3> vertices;
    unsigned numGeometries = custom->GetNumGeometries();
    
    for (unsigned i = 0; i < numGeometries; ++i)
    {
        Geometry* geom = custom->GetLodGeometry(i, 0);
        if (!geom)
        {
            LOGWARNING("Skipping null geometry for convex hull collision");
            continue;
        }
        
        const unsigned char* vertexData;
        const unsigned char* indexData;
        unsigned vertexSize;
        unsigned indexSize;
        unsigned elementMask;
        
        geom->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
        if (!vertexData)
        {
            LOGWARNING("Skipping geometry with no CPU-side geometry data for convex hull collision - no vertex data");
            continue;
        }
        
        unsigned vertexStart = geom->GetVertexStart();
        unsigned vertexCount = geom->GetVertexCount();
        
        // Copy vertex data
        for (unsigned j = 0; j < vertexCount; ++j)
        {
            const Vector3& v = *((const Vector3*)(&vertexData[(vertexStart + j) * vertexSize]));
            vertices.Push(v);
        }
    }
    
    BuildHull(vertices);
}
Exemple #4
0
bool StaticModel::DrawOcclusion(OcclusionBuffer* buffer)
{
    for (unsigned i = 0; i < batches_.size(); ++i)
    {
        Geometry* geometry = GetLodGeometry(i, occlusionLodLevel_);
        if (!geometry)
            continue;

        // Check that the material is suitable for occlusion (default material always is) and set culling mode
        Material* material = batches_[i].material_;
        if (material)
        {
            if (!material->GetOcclusion())
                continue;
            buffer->SetCullMode(material->GetCullMode());
        }
        else
            buffer->SetCullMode(CULL_CCW);

        const unsigned char* vertexData;
        unsigned vertexSize;
        const unsigned char* indexData;
        unsigned indexSize;
        const ea::vector<VertexElement>* elements;

        geometry->GetRawData(vertexData, vertexSize, indexData, indexSize, elements);
        // Check for valid geometry data
        if (!vertexData || !indexData || !elements || VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3, SEM_POSITION) != 0)
            continue;

        unsigned indexStart = geometry->GetIndexStart();
        unsigned indexCount = geometry->GetIndexCount();

        // Draw and check for running out of triangles
        if (!buffer->AddTriangles(node_->GetWorldTransform(), vertexData, vertexSize, indexData, indexSize, indexStart, indexCount))
            return false;
    }

    return true;
}
Exemple #5
0
void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target, unsigned batchIndex, const Frustum& frustum,
    const Vector3& decalNormal, float normalCutoff)
{
    // Try to use the most accurate LOD level if possible
    Geometry* geometry = target->GetLodGeometry(batchIndex, 0);
    if (!geometry || geometry->GetPrimitiveType() != TRIANGLE_LIST)
        return;

    const unsigned char* positionData = 0;
    const unsigned char* normalData = 0;
    const unsigned char* skinningData = 0;
    const unsigned char* indexData = 0;
    unsigned positionStride = 0;
    unsigned normalStride = 0;
    unsigned skinningStride = 0;
    unsigned indexStride = 0;

    IndexBuffer* ib = geometry->GetIndexBuffer();
    if (ib)
    {
        indexData = ib->GetShadowData();
        indexStride = ib->GetIndexSize();
    }

    // For morphed models positions, normals and skinning may be in different buffers
    for (unsigned i = 0; i < geometry->GetNumVertexBuffers(); ++i)
    {
        VertexBuffer* vb = geometry->GetVertexBuffer(i);
        if (!vb)
            continue;

        unsigned elementMask = vb->GetElementMask();
        unsigned char* data = vb->GetShadowData();
        if (!data)
            continue;

        if (elementMask & MASK_POSITION)
        {
            positionData = data;
            positionStride = vb->GetVertexSize();
        }
        if (elementMask & MASK_NORMAL)
        {
            normalData = data + vb->GetElementOffset(SEM_NORMAL);
            normalStride = vb->GetVertexSize();
        }
        if (elementMask & MASK_BLENDWEIGHTS)
        {
            skinningData = data + vb->GetElementOffset(SEM_BLENDWEIGHTS);
            skinningStride = vb->GetVertexSize();
        }
    }

    // Positions and indices are needed
    if (!positionData)
    {
        // As a fallback, try to get the geometry's raw vertex/index data
        const PODVector<VertexElement>* elements;
        geometry->GetRawData(positionData, positionStride, indexData, indexStride, elements);
        if (!positionData)
        {
            URHO3D_LOGWARNING("Can not add decal, target drawable has no CPU-side geometry data");
            return;
        }
    }

    if (indexData)
    {
        unsigned indexStart = geometry->GetIndexStart();
        unsigned indexCount = geometry->GetIndexCount();

        // 16-bit indices
        if (indexStride == sizeof(unsigned short))
        {
            const unsigned short* indices = ((const unsigned short*)indexData) + indexStart;
            const unsigned short* indicesEnd = indices + indexCount;

            while (indices < indicesEnd)
            {
                GetFace(faces, target, batchIndex, indices[0], indices[1], indices[2], positionData, normalData, skinningData,
                    positionStride, normalStride, skinningStride, frustum, decalNormal, normalCutoff);
                indices += 3;
            }
        }
        else
        // 32-bit indices
        {
            const unsigned* indices = ((const unsigned*)indexData) + indexStart;
            const unsigned* indicesEnd = indices + indexCount;

            while (indices < indicesEnd)
            {
                GetFace(faces, target, batchIndex, indices[0], indices[1], indices[2], positionData, normalData, skinningData,
                    positionStride, normalStride, skinningStride, frustum, decalNormal, normalCutoff);
                indices += 3;
            }
        }
    }
    else
    {
        // Non-indexed geometry
        unsigned indices = geometry->GetVertexStart();
        unsigned indicesEnd = indices + geometry->GetVertexCount();

        while (indices + 2 < indicesEnd)
        {
            GetFace(faces, target, batchIndex, indices, indices + 1, indices + 2, positionData, normalData, skinningData,
                positionStride, normalStride, skinningStride, frustum, decalNormal, normalCutoff);
            indices += 3;
        }
    }
}