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.entities << ent; } entData->Blocks << █ } if(isMeshEnt && ent->bRenderable) { MeshEntity *meshEnt = (MeshEntity*)ent; meshEnt->ResetTransform(); if(block.bounds.IntersectsOBB(meshEnt->bounds, meshEnt->transform)) { block.visMeshEntities << meshEnt; entData->VisBlocks << █ } } } //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.visLights << light; } } else if(light->IsOf(GetClass(DirectionalLight))) { entData->VisBlocks << █ block.visLights << light; } else { PointLight *point = static_cast<PointLight*>(light); if(block.bounds.SphereIntersects(point->GetWorldPos(), point->lightRange)) { entData->VisBlocks << █ block.visLights << light; } } } } } }
void OctLevel::CalcRenderOrderRecurse(const Vect &eye, const ViewClip &clip, MeshOrderInfo &meshOrder, OctNode *curNode, BOOL bFullyVisible) { OctNode *node = (curNode != NULL) ? curNode : objectTree->GetRoot(); DWORD i; BOOL bCheckBounds = (node->numChildren > 1) || (node->Leaves.Num() > 0); if(!bFullyVisible && bCheckBounds) { int testVal = clip.BoundsTest(node->bounds); if(testVal == BOUNDS_INSIDE) bFullyVisible = TRUE; else if(testVal == BOUNDS_OUTSIDE) return; } if(node->numChildren) { for(i=0; i<8; i++) { if(!node->children[i]) continue; OctNode *child = node->children[i]; CalcRenderOrderRecurse(eye, clip, meshOrder, child, bFullyVisible); } } for(i=0; i<node->Leaves.Num(); i++) { LevelObject *leaf = node->Leaves[i]; if(!bFullyVisible && !clip.BoundsVisible(leaf->bounds)) continue; if(leaf->type == ObjectType_Entity) { if(leaf->ent->IsOf(GetClass(MeshEntity))) { MeshEntity *meshEnt = (MeshEntity*)leaf->ent; if(meshEnt->bRenderable) { EntityVisible(meshEnt) = TRUE; meshOrder.AddEntity(meshEnt); } } else if(leaf->ent->IsOf(GetClass(Projector))) { Projector *projector = (Projector*)leaf->ent; if(projector->bRenderable) { if(projector->IsOf(GetClass(LitDecal))) renderLitDecals << (LitDecal*)projector; else renderProjectors << projector; EntityVisible(projector) = TRUE; } } else if(leaf->ent->IsOf(GetClass(Light))) { Light *light = (Light*)leaf->ent; if(light->IsOf(GetClass(SpotLight))) { SpotLight *spotLight = (SpotLight*)light; if(spotLight->IsLightmapped() && !spotLight->NumLitEntities()) continue; renderSpotLights << spotLight; } else if(light->IsOf(GetClass(PointLight))) { PointLight *pointLight = (PointLight*)light; if(pointLight->IsLightmapped() && !pointLight->NumLitEntities()) continue; renderPointLights << pointLight; } } else { Entity *ent = leaf->ent; if(ent->bRenderable) { EntityVisible(ent) = TRUE; renderEntities << ent; } } } else if(leaf->type == ObjectType_Brush) { Brush *brush = leaf->brush; brush->bVisible = TRUE; renderBrushes << brush; } } }