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);
    }
}
Exemple #4
0
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);
	}
}
Exemple #7
0
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;
}
Exemple #8
0
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()));
	}
}
Exemple #11
0
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);
    }
}