Пример #1
0
void OutdoorLevel::UpdateEntityPositionData(Entity *ent, const Matrix &transform)
{
    BOOL isLight = ent->IsOf(GetClass(Light));
    BOOL isMeshEnt = ent->IsOf(GetClass(MeshEntity));
    OutdoorEntityData *entData = GetOutdoorEntityData(ent);
    int i;

    //-------------------------------------------------------------------------------

    if(isMeshEnt)
    {
        MeshEntity *meshEnt = (MeshEntity*)ent;
        meshEnt->ResetTransform();
    }

    Bounds entBounds = ent->GetBounds();
    for(i=0; i<TerrainBlocks.Num(); i++)
    {
        TerrainBlock &block = TerrainBlocks[i];
        if(block.bounds.Intersects(entBounds))
        {
            if(isLight)
            {
                Light *light = static_cast<Light*>(ent);
                block.lights << light;
            }
            else
            {
                if(!isMeshEnt && ent->bRenderable)
                {
                    block.visEntities << ent;
                    entData->VisBlocks << &block;
                }
                block.entities << ent;
            }
            entData->Blocks << &block;
        }

        if(isMeshEnt && ent->bRenderable)
        {
            MeshEntity *meshEnt = (MeshEntity*)ent;

            meshEnt->ResetTransform();

            if(block.bounds.IntersectsOBB(meshEnt->bounds, meshEnt->transform))
            {
                block.visMeshEntities << meshEnt;
                entData->VisBlocks << &block;
            }
        }
    }


    //recalculate light visibility data
    if(isLight)
    {
        Light *light = (Light*)ent;

        if(!light->IsOff() && !(light->color&0xFFFFFF))
        {
            for(i=0; i<TerrainBlocks.Num(); i++)
            {
                TerrainBlock &block = TerrainBlocks[i];
                if(light->IsOf(GetClass(SpotLight)))
                {
                    SpotLight *spot = static_cast<SpotLight*>(light);
                    ViewClip clip;
                    Matrix rotMatrix = spot->GetEntityInvTransform();

                    clip.planes.Clear();
                    clip.SetPerspective(spot->cutoff+1.0f, 1.0f, 1.0, 4096.0f);
                    clip.Transform(rotMatrix.GetTranspose());

                    if(clip.BoundsVisible(block.bounds) && block.bounds.SphereIntersects(spot->GetWorldPos(), spot->lightRange))
                    {
                        entData->VisBlocks << &block;
                        block.visLights << light;
                    }
                }
                else if(light->IsOf(GetClass(DirectionalLight)))
                {
                    entData->VisBlocks << &block;
                    block.visLights << light;
                }
                else
                {
                    PointLight *point = static_cast<PointLight*>(light);

                    if(block.bounds.SphereIntersects(point->GetWorldPos(), point->lightRange))
                    {
                        entData->VisBlocks << &block;
                        block.visLights << light;
                    }
                }
            }
        }
    }
}