void NodesPropertyControl::WillDisappear() { LodComponent *lodComponent = GetLodComponent(currentSceneNode); if(lodComponent) { lodComponent->SetForceDistance(LodComponent::INVALID_DISTANCE); } else { if(propertyList->IsPropertyAvaliable(String("property.lodnode.forcedistance")) && propertyList->GetBoolPropertyValue(String("property.lodnode.forcedistance"))) { RestoreChildLodDistances(); } for(int32 i = 0; i < (int32)childLodComponents.size(); ++i) { childLodComponents[i]->SetForceDistance(LodComponent::INVALID_DISTANCE); } ReleaseChildLodData(); } SafeRelease(currentSceneNode); }
void RecursiveProcessLodNode(Entity * curr, int32 lod, void * userData, void(*process)(Entity*, void*)) { LodComponent * lodComp = (LodComponent*)curr->GetComponent(Component::LOD_COMPONENT); if (lodComp) { Vector<LodComponent::LodData*> retLodLayers; lodComp->GetLodData(retLodLayers); for (Vector<LodComponent::LodData*>::iterator it = retLodLayers.begin(); it != retLodLayers.end(); ++it) { LodComponent::LodData * data = *it; if (data->layer == lod) { for (Vector<Entity*>::iterator i = data->nodes.begin(); i != data->nodes.end(); ++i) { process((*i), userData); } break; } } } else { for (int32 i = 0; i < curr->GetChildrenCount(); i++) RecursiveProcessLodNode(curr->GetChild(i), lod, userData, process); } }
void NodesPropertyControl::OnSliderPropertyChanged(PropertyList *, const String &forKey, float32 newValue) { if("property.lodnode.distanceslider" == forKey) { if(propertyList->GetBoolPropertyValue("property.lodnode.forcedistance")) { LodComponent *lodComponent = GetLodComponent(currentSceneNode); if(lodComponent) { lodComponent->SetForceDistance(newValue); } else { for(int32 i = 0; i < (int32)childLodComponents.size(); ++i) { childLodComponents[i]->SetForceDistance(newValue); } } } } if(nodesDelegate) { nodesDelegate->NodesPropertyChanged(forKey); } }
void EditorScene::SetForceLodLayerRecursive(Entity *node, int32 layer) { LodComponent *lc = GetLodComponent(node); if(lc) { lc->SetForceLodLayer(layer); } int32 count = node->GetChildrenCount(); for(int32 i = 0; i < count; ++i) { SetForceLodLayerRecursive(node->GetChild(i), layer); } }
void LodSystem::RecheckLod(SceneNode * entity) { LodComponent * lodComponent = static_cast<LodComponent*>(entity->GetComponent(Component::LOD_COMPONENT)); if (!lodComponent->currentLod)return; if(LodComponent::INVALID_LOD_LAYER != lodComponent->forceLodLayer) { for (Vector<LodComponent::LodData>::iterator it = lodComponent->lodLayers.begin(); it != lodComponent->lodLayers.end(); it++) { if (it->layer >= lodComponent->forceLodLayer) { lodComponent->currentLod = &(*it); return; } } return; } { float32 dst = 0.f; if(LodComponent::INVALID_DISTANCE == lodComponent->forceDistance) { if(camera) { dst = (camera->GetPosition() - entity->GetWorldTransform().GetTranslationVector()).SquareLength(); dst *= camera->GetZoomFactor() * camera->GetZoomFactor(); } } else { dst = lodComponent->forceDistanceSq; } if (dst > lodComponent->GetLodLayerFarSquare(lodComponent->currentLod->layer) || dst < lodComponent->GetLodLayerNearSquare(lodComponent->currentLod->layer)) { for (Vector<LodComponent::LodData>::iterator it = lodComponent->lodLayers.begin(); it != lodComponent->lodLayers.end(); it++) { if (dst >= lodComponent->GetLodLayerNearSquare(it->layer)) { lodComponent->currentLod = &(*it); } else { return; } } } } }
void LodSystem::LodMerger::MergeChildLods() { LodComponent * toLod = (LodComponent*)toEntity->GetOrCreateComponent(Component::LOD_COMPONENT); Vector<SceneNode*> allLods; GetLodComponentsRecursive(toEntity, allLods); uint32 count = allLods.size(); for(uint32 i = 0; i < count; ++i) { LodComponent * fromLod = GetLodComponent(allLods[i]); int32 fromLodsCount = fromLod->GetMaxLodLayer(); for(int32 l = 0; l < fromLodsCount; ++l) { LodComponent::LodData & fromData = fromLod->lodLayers[l]; int32 lodLayerIndex = fromData.layer; LodComponent::LodData * toData = 0; int32 maxLod = toLod->GetMaxLodLayer(); //create loddata if needed if(lodLayerIndex > maxLod) { DVASSERT(maxLod == lodLayerIndex-1); toLod->lodLayers.push_back(fromData); toData = &(toLod->lodLayers[lodLayerIndex]); toData->nodes.clear(); toData->indexes.clear(); //indeces will not have any sense after lod merge toLod->lodLayersArray = fromLod->lodLayersArray; } else { toData = &(toLod->lodLayers[lodLayerIndex]); } uint32 nodesToCopy = fromData.nodes.size(); for(uint32 j = 0; j < nodesToCopy; ++j) { toData->nodes.push_back(fromData.nodes[j]); } } allLods[i]->RemoveComponent(Component::LOD_COMPONENT); } }
int32 EditorScene::GetForceLodLayer(Entity *node) { if(!node) return -1; LodComponent *lc = GetLodComponent(node); if(lc) return lc->GetForceLodLayer(); int32 count = node->GetChildrenCount(); for(int32 i = 0; i < count; ++i) { int32 layer = GetForceLodLayer(node->GetChild(i)); if(-1 != layer) return layer; } return -1; }
void EditorScene::SetForceLodLayer(Entity *node, int32 layer) { if(!node) return; Entity *n = node; do { LodComponent *lc = GetLodComponent(n); if(lc) { lc->SetForceLodLayer(layer); } n = n->GetParent(); } while (n); SetForceLodLayerRecursive(node, layer); }
void SceneValidator::ValidateLodComponent(Entity *ownerNode, Set<String> &errorsLog) { LodComponent *lodComponent = GetLodComponent(ownerNode); if(!lodComponent) return; int32 layersCount = lodComponent->GetLodLayersCount(); if (GetEmitter(ownerNode)) layersCount = LodComponent::MAX_LOD_LAYERS; if(layersCount == 0) { errorsLog.insert(Format("Node %s: Count of layers is 0", ownerNode->GetName().c_str())); } for(int32 layer = 0; layer < layersCount; ++layer) { float32 distance = lodComponent->GetLodLayerDistance(layer); if(LodComponent::INVALID_DISTANCE == distance) { //TODO: why this function isn't realized for lodcomponent? lodComponent->SetLodLayerDistance(layer, LodComponent::GetDefaultDistance(layer)); errorsLog.insert(Format("Node %s: lod distances weren't correct. Re-save.", ownerNode->GetName().c_str())); } } Vector<LodComponent::LodData *>lodLayers; lodComponent->GetLodData(lodLayers); Vector<LodComponent::LodData *>::const_iterator endIt = lodLayers.end(); int32 layer = 0; for(Vector<LodComponent::LodData *>::iterator it = lodLayers.begin(); it != endIt; ++it, ++layer) { LodComponent::LodData * ld = *it; if(ld->layer != layer) { ld->layer = layer; errorsLog.insert(Format("Node %s: lod layers weren't correct. Rename childs. Re-save.", ownerNode->GetName().c_str())); } } }
void LodSystem::UpdateEntityAfterLoad(SceneNode * entity) { LodComponent * lod = static_cast<LodComponent*>(entity->GetComponent(Component::LOD_COMPONENT)); for (Vector<LodComponent::LodData>::iterator it = lod->lodLayers.begin(); it != lod->lodLayers.end(); ++it) { LodComponent::LodData & ld = *it; size_t size = ld.indexes.size(); for (size_t idx = 0; idx < size; ++idx) { SceneNode * childEntity = entity->GetChild(ld.indexes[idx]); ld.nodes.push_back(childEntity); { childEntity->SetLodVisible(false); } } } lod->currentLod = NULL; if(lod->lodLayers.size() > 0) { lod->SetCurrentLod(&(*lod->lodLayers.rbegin())); } }
void LodNodePropertyControl::ReadFrom(Entity * sceneNode) { NodesPropertyControl::ReadFrom(sceneNode); LodComponent *lodComponent = GetLodComponent(sceneNode); DVASSERT(lodComponent); propertyList->AddSection("property.lodnode", GetHeaderState("property.lodnode", true)); propertyList->AddBoolProperty("property.lodnode.forcedistance"); propertyList->SetBoolPropertyValue("property.lodnode.forcedistance", false); propertyList->AddSliderProperty("property.lodnode.distanceslider", false); propertyList->SetSliderPropertyValue("property.lodnode.distanceslider", 0, LodComponent::MAX_LOD_DISTANCE, LodComponent::MIN_LOD_DISTANCE); int32 lodCount = lodComponent->GetLodLayersCount(); if(1 < lodCount) { propertyList->AddDistanceProperty("property.lodnode.distances"); float32 *distances = new float32[lodComponent->GetLodLayersCount()]; int32 *triangles = new int32[lodComponent->GetLodLayersCount()]; Vector<LodComponent::LodData*> lodLayers; lodComponent->GetLodData(lodLayers); Vector<LodComponent::LodData*>::const_iterator lodLayerIt = lodLayers.begin(); for(int32 i = 0; i < lodComponent->GetLodLayersCount(); ++i) { distances[i] = lodComponent->GetLodLayerDistance(i); LodComponent::LodData *layer = *lodLayerIt; triangles[i] = GetTrianglesForLodLayer(layer); ++lodLayerIt; } propertyList->SetDistancePropertyValue("property.lodnode.distances", distances, triangles, lodComponent->GetLodLayersCount()); SafeDeleteArray(distances); SafeDeleteArray(triangles); } }
Component * LodComponent::Clone(Entity * toEntity) { LodComponent * newLod = new LodComponent(); newLod->SetEntity(toEntity); newLod->lodLayers = lodLayers; const Vector<LodData>::const_iterator endLod = newLod->lodLayers.end(); for (Vector<LodData>::iterator it = newLod->lodLayers.begin(); it != endLod; ++it) { LodData & ld = *it; ld.nodes.clear(); } //if(!newLod->lodLayers.empty()) //{ // const List<LodData>::const_iterator endLod = newLod->lodLayers.end(); // newLod->currentLod = &(*newLod->lodLayers.begin()); // for (List<LodData>::iterator it = newLod->lodLayers.begin(); it != endLod; ++it) // { // LodData & ld = *it; // uint32 size = ld.nodes.size(); // for (uint32 idx = 0; idx < size; ++idx) // { // int32 count = entity->GetChildrenCount(); // for (int32 i = 0; i < count; i++) // { // Entity * child = entity->GetChild(i); // if(child == ld.nodes[idx]) // { // ld.nodes[idx] = toEntity->GetChild(i); // if (newLod->currentLod != &ld) // { // ld.nodes[idx]->SetUpdatable(false); // } // else // { // ld.nodes[idx]->SetUpdatable(true); // } // break; // } // } // } // } //} //Lod values for(int32 iLayer = 0; iLayer < MAX_LOD_LAYERS; ++iLayer) { newLod->lodLayersArray[iLayer].distance = lodLayersArray[iLayer].distance; newLod->lodLayersArray[iLayer].nearDistance = lodLayersArray[iLayer].nearDistance; newLod->lodLayersArray[iLayer].nearDistanceSq = lodLayersArray[iLayer].nearDistanceSq; newLod->lodLayersArray[iLayer].farDistance = lodLayersArray[iLayer].farDistance; newLod->lodLayersArray[iLayer].farDistanceSq = lodLayersArray[iLayer].farDistanceSq; } newLod->forceDistance = forceDistance; newLod->forceDistanceSq = forceDistanceSq; newLod->forceLodLayer = forceLodLayer; return newLod; }
bool SwitchToRenerObjectConverter::MergeSwitch(Entity * entity) { Vector<Entity*> entitiesToRemove; SwitchComponent * sw = GetSwitchComponent(entity); if(sw) { RenderComponent * rc = GetRenderComponent(entity); RenderObject * ro = 0; if(!rc) { ro = new Mesh(); rc = new RenderComponent(ro); ro->Release(); ro->SetAABBox(AABBox3(Vector3(0, 0, 0), Vector3(0, 0, 0))); entity->AddComponent(rc); } else { ro = rc->GetRenderObject(); } DVASSERT(ro); int32 size = entity->GetChildrenCount(); for(int32 i = 0; i < size; ++i) { Entity * sourceEntity = entity->GetChild(i); RenderObject * sourceRenderObject = GetRenderObject(sourceEntity); //workaround for custom properties for crashed model if(1 == i) // crash model { KeyedArchive *childProps = GetCustomPropertiesArchieve(sourceEntity); if(childProps && childProps->IsKeyExists("CollisionType")) { KeyedArchive *entityProps = GetOrCreateCustomProperties(entity)->GetArchive(); entityProps->SetInt32("CollisionTypeCrashed", childProps->GetInt32("CollisionType", 0)); } } //end of custom properties Vector<std::pair<Entity*, RenderObject*> > renderPairs; if(sourceRenderObject) { renderPairs.push_back(std::make_pair(sourceEntity, sourceRenderObject)); } else { FindRenderObjectsRecursive(sourceEntity, renderPairs); DVASSERT(renderPairs.size() == 1); sourceRenderObject = renderPairs[0].second; } if(sourceRenderObject) { TransformComponent * sourceTransform = GetTransformComponent(sourceEntity); if (sourceTransform->GetLocalTransform() != Matrix4::IDENTITY) { PolygonGroup * pg = sourceRenderObject->GetRenderBatchCount() > 0 ? sourceRenderObject->GetRenderBatch(0)->GetPolygonGroup() : 0; if(pg && bakedPolygonGroups.end() == bakedPolygonGroups.find(pg)) { sourceRenderObject->BakeGeometry(sourceTransform->GetLocalTransform()); bakedPolygonGroups.insert(pg); } } uint32 sourceSize = sourceRenderObject->GetRenderBatchCount(); while(sourceSize) { int32 lodIndex, switchIndex; RenderBatch * sourceRenderBatch = sourceRenderObject->GetRenderBatch(0, lodIndex, switchIndex); sourceRenderBatch->Retain(); sourceRenderObject->RemoveRenderBatch(sourceRenderBatch); ro->AddRenderBatch(sourceRenderBatch, lodIndex, i); sourceRenderBatch->Release(); sourceSize--; } } renderPairs[0].first->RemoveComponent(Component::RENDER_COMPONENT); LodComponent * lc = GetLodComponent(sourceEntity); if((0 != lc) && (0 == GetLodComponent(entity))) { LodComponent * newLod = (LodComponent*)lc->Clone(entity); entity->AddComponent(newLod); } renderPairs[0].first->RemoveComponent(Component::LOD_COMPONENT); if(sourceEntity->GetChildrenCount() == 0) { entitiesToRemove.push_back(sourceEntity); } } } uint32 entitiesToRemoveCount = entitiesToRemove.size(); for(uint32 i = 0; i < entitiesToRemoveCount; ++i) { entitiesToRemove[i]->GetParent()->RemoveNode(entitiesToRemove[i]); } return false; }
void NodesPropertyControl::OnBoolPropertyChanged(PropertyList *, const String &forKey, bool newValue) { if(currentSceneNode) { KeyedArchive *customProperties = currentSceneNode->GetCustomProperties(); if(SCENE_NODE_USED_IN_STATIC_LIGHTING_PROPERTY_NAME == forKey) { customProperties->SetBool("editor.staticlight.used", newValue); } else if(SCENE_NODE_CAST_SHADOWS_PROPERTY_NAME == forKey) { customProperties->SetBool("editor.staticlight.castshadows", newValue); } else if(SCENE_NODE_RECEIVE_SHADOWS_PROPERTY_NAME == forKey) { customProperties->SetBool("editor.staticlight.receiveshadows", newValue); } else if("property.lodnode.forcedistance" == forKey) { float32 forceDistance = (newValue) ? propertyList->GetSliderPropertyValue("property.lodnode.distanceslider") : LodComponent::INVALID_DISTANCE; LodComponent *lodComponent = GetLodComponent(currentSceneNode); if(lodComponent) { lodComponent->SetForceDistance(forceDistance); } else { if(newValue) SetChildLodDistances(); else RestoreChildLodDistances(); for(int32 i = 0; i < (int32)childLodComponents.size(); ++i) { childLodComponents[i]->SetForceDistance(forceDistance); } } } // else if("CollisionFlag" == forKey) // { // currentSceneNode->PropagateBoolProperty("CollisionFlag", newValue); // } if(!createNodeProperties) { KeyedArchive *customProperties = currentSceneNode->GetCustomProperties(); if (forKey == SCENE_NODE_IS_VISIBLE_PROPERTY_NAME) { currentSceneNode->SetVisible(newValue); } if(customProperties->IsKeyExists(forKey)) { customProperties->SetBool(forKey, newValue); } } else { KeyedArchive *customProperties = currentSceneNode->GetCustomProperties(); if(customProperties->IsKeyExists(forKey)) { customProperties->SetBool(forKey, newValue); } } } if(nodesDelegate) { nodesDelegate->NodesPropertyChanged(forKey); } }