bool CClusterGen::StoreLineSegmentCluster()
{
	int currClusterId = 0;

	for (int i = 0; i < m_currComponentId; i++)
	{
		if (m_lineSegmentClusters[i].enabled)
		{
			// store the clusters finally identified
			// START ...
			CCluster* pClusterItem = new CCluster(currClusterId, m_document->m_nDimensions); 
			m_document->m_clusterList.push_back(pClusterItem);

			for (int j = 0; j < m_lineSegmentClusters[i].nClusterPoints; j++)
				pClusterItem->AddPointToArray(m_lineSegmentClusters[i].clusterPointArray[j]);

			pClusterItem->SetDensity(m_lineSegmentClusters[i].nTrajectories);
			pClusterItem->SetDifferentSegmentInCluster(m_lineSegmentClusters[i].nLineSegments);

			currClusterId++;	// increase the number of final clusters
			// ... END
		}
	}

	m_document->m_nClusters = currClusterId;

	return true;
}
Exemplo n.º 2
0
ICluster * CreateCluster(const CString & url, const LogicalCluster * data)
{
	CCluster * attr = CreateClusterRaw(url, data->Name);
	ATLASSERT(attr);
	attr->Update(data);
	return attr;
}
Exemplo n.º 3
0
int main()
#endif
{
	double rGlobalTime = 0;
	double rOldGlobalTime = 0;
	double rDeltaTime = 0;

	vector<SDispCS> DispCS;

	bool bAutoDetect = true;
	bool bDisplay = true;
	sint32 nSelected = 0;

	SDispCS dcsTemp;

	vector<CInstanceGroup*> vAllIGs;
	// 2 dynamics objects
	CTransformShape *pDynObj_InRoot;
	CTransformShape *pDynObj_InCS;

	CNELU::init (800, 600, CViewport(), 32, true);

	CNELU::Scene->enableLightingSystem(true);
	CNELU::Scene->setAmbientGlobal(CRGBA(128,128,128));

	CPath::addSearchPath(CV_DIR);
	CPath::addSearchPath(CV_DIR"/shapes");
	CPath::addSearchPath(CV_DIR"/groups");
	CPath::addSearchPath(CV_DIR"/fonts");

	CFontManager FontManager;
	CTextContext TextContext;

	TextContext.init (CNELU::Driver, &FontManager);	
	TextContext.setFontGenerator (NLMISC::CPath::lookup("n019003l.pfb"));
	TextContext.setHotSpot (CComputedString::TopLeft);
	TextContext.setColor (CRGBA(255,255,255));
	TextContext.setFontSize (20);

	CEvent3dMouseListener MouseListener;
	MouseListener.addToServer (CNELU::EventServer);
	MouseListener.setFrustrum (CNELU::Camera->getFrustum());
	MouseListener.setMouseMode (CEvent3dMouseListener::firstPerson);
	
	CNELU::Camera->setTransformMode (ITransformable::DirectMatrix);
	// Force to automatically find the cluster system
	CNELU::Camera->setClusterSystem ((CInstanceGroup*)-1); 

	CClipTrav *pClipTrav = (CClipTrav*)&(CNELU::Scene->getClipTrav());
	dcsTemp.Name = "Root";
	dcsTemp.pIG = NULL;
	DispCS.push_back (dcsTemp);

	// Add all instance that create the scene
	// --------------------------------------	
	// Beginning of script reading
	CVector CameraStart;

	LoadSceneScript ("main.cvs", CNELU::Scene, DispCS, CameraStart, vAllIGs);

	CMatrix m = MouseListener.getViewMatrix();
	m.setPos (CameraStart);
	MouseListener.setMatrix (m);
	// End of script reading

	// Put a dynamic object in the root
	pDynObj_InRoot = CNELU::Scene->createInstance ("sphere01.shape");
	pDynObj_InRoot->setPos (0.0f, 0.0f, 0.0f);
	// Put a dynamic object inside
	pDynObj_InCS = CNELU::Scene->createInstance ("sphere01.shape");
	pDynObj_InCS->setPos (50.0f, 50.0f, 25.0f);
	// No automatic detection for moving objects - setup in street
	pDynObj_InCS->setClusterSystem (vAllIGs[0]);


	// Main loop
	do
	{
		rGlobalTime = CTime::ticksToSecond(CTime::getPerformanceTime());
		rDeltaTime = rGlobalTime - rOldGlobalTime;
		rOldGlobalTime = rGlobalTime;

		pDynObj_InRoot->setPos	(-20.0f+20.0f*sinf((float)rGlobalTime), 
								-20.0f+20.0f*cosf((float)rGlobalTime*1.2f), 
								20.0f*sinf((float)rGlobalTime*1.1f+0.5f));

		pDynObj_InCS->setPos	(25.0f+5.0f*sinf((float)rGlobalTime*1.4f), 
								-25.0f+5.0f*cosf((float)rGlobalTime*1.3f), 
								25.0f+2.0f*sinf((float)rGlobalTime*1.2f+0.7f));


		CNELU::Scene->animate ((float)rGlobalTime);

		CNELU::EventServer.pump();

		CNELU::clearBuffers (CRGBA(0,0,0));

		CNELU::Scene->render ();

		// -----------------------------------------------------
		// -----------------------------------------------------
		if (bDisplay)
		{
			vector<CCluster*> vCluster;
			DispCS[0].pIG = pClipTrav->RootCluster->Group;
			TextContext.setColor (CRGBA(255,255,255,255));
			if (bAutoDetect)
			{
				TextContext.printfAt (0, 1, "AutoDetect : ON");
				
				pClipTrav->fullSearch (vCluster, pClipTrav->CamPos);

				for (uint32 i = 0; i < DispCS.size(); ++i)
				{
					TextContext.setColor (CRGBA(255,255,255,255));
					for( uint32 j = 0; j < vCluster.size(); ++j)
					{
						if (DispCS[i].pIG == vCluster[j]->Group)
						{
							TextContext.setColor (CRGBA(255,0,0,255));
							break;
						}
					}

					TextContext.printfAt (0, 1-(i+2)*0.028f, DispCS[i].Name.c_str());
				}

			}
			else
			{
				TextContext.printfAt (0, 1, "AutoDetect : OFF");

				CInstanceGroup *pCurIG = CNELU::Camera->getClusterSystem();
				for (uint32 i = 0; i < DispCS.size(); ++i)
				{
					if (DispCS[i].pIG == pCurIG)
						TextContext.setColor (CRGBA(255,0,0,255));
					else
						TextContext.setColor (CRGBA(255,255,255,255));

					TextContext.printfAt (0, 1-(i+2)*0.028f, DispCS[i].Name.c_str());
				}

				TextContext.setColor (CRGBA(255,255,255,255));

				pClipTrav->Accel.select (pClipTrav->CamPos, pClipTrav->CamPos);
				CQuadGrid<CCluster*>::CIterator itAcc = pClipTrav->Accel.begin();
				while (itAcc != pClipTrav->Accel.end())
				{
					CCluster *pCluster = *itAcc;
					if (pCluster->Group == pClipTrav->Camera->getClusterSystem())
					if (pCluster->isIn (pClipTrav->CamPos))
					{
						vCluster.push_back (pCluster);
					}
					++itAcc;
				}
				if ((vCluster.size() == 0) && (DispCS[0].pIG == pCurIG))
				{
					vCluster.push_back (pClipTrav->RootCluster);
				}

			}			

			TextContext.setColor (CRGBA(255,255,255,255));

			string sAllClusters = "";
			for( uint32 j = 0; j < vCluster.size(); ++j)
			{
				sAllClusters += vCluster[j]->Name;
				if (j < (vCluster.size()-1))
					sAllClusters += ",  ";
			}
			TextContext.printfAt (0, 1-0.028f, sAllClusters.c_str());
		}

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

		CNELU::Driver->swapBuffers ();

		// Keys management
		// ---------------

		if (CNELU::AsyncListener.isKeyDown (KeySHIFT))
			MouseListener.setSpeed (50.0f);
		else
			MouseListener.setSpeed (10.0f);

		CNELU::Camera->setMatrix (MouseListener.getViewMatrix());

		if (CNELU::AsyncListener.isKeyPushed(KeyL))
		{
			CNELU::Driver->setPolygonMode (IDriver::Line);
		}

		if (CNELU::AsyncListener.isKeyPushed (KeyP))
		{
			CNELU::Driver->setPolygonMode (IDriver::Filled);
		}

		if (CNELU::AsyncListener.isKeyPushed (KeyTAB))
			bDisplay = !bDisplay;

		if (CNELU::AsyncListener.isKeyPushed (KeyA))
		{
			if (bAutoDetect)
			{
				bAutoDetect = false;
				CNELU::Camera->setClusterSystem (NULL);
				nSelected = 0;
			}
			else
			{
				bAutoDetect = true;
				CNELU::Camera->setClusterSystem ((CInstanceGroup*)-1);
			}
		}

		if (!bAutoDetect)
		{
			if (CNELU::AsyncListener.isKeyPushed (KeyZ))
			{
				nSelected--;
				if(nSelected == -1)
					nSelected = (sint32)DispCS.size()-1;
			}
			if (CNELU::AsyncListener.isKeyPushed (KeyS))
			{
				nSelected++;
				if(nSelected == (sint32)DispCS.size())
					nSelected = 0;
			}
			CNELU::Camera->setClusterSystem (DispCS[nSelected].pIG);
		}

	}
	while ((!CNELU::AsyncListener.isKeyPushed(KeyESCAPE)) && CNELU::Driver->isActive());

	return EXIT_SUCCESS;
}
Exemplo n.º 4
0
CInstanceGroup*	CExportNel::buildInstanceGroup(const vector<INode*>& vectNode, vector<INode*>& resultInstanceNode, TimeValue tvTime)
{
	// Extract from the node the name, the transformations and the parent

	CInstanceGroup::TInstanceArray aIGArray;
	uint32 i, nNumIG;
	uint32 j,k,m;

	aIGArray.empty ();
	resultInstanceNode.empty ();
	aIGArray.resize (vectNode.size());
	resultInstanceNode.resize (vectNode.size());

	int nNbInstance = 0;
	for (i = 0; i < vectNode.size(); ++i)
	{
		INode *pNode = vectNode[i];

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh (*pNode, tvTime) || CExportNel::isDummy(*pNode, tvTime))
		{
			++nNbInstance;
		}
	}

	// Check integrity of the hierarchy and set the parents
	std::vector<INode*>::const_iterator it = vectNode.begin();
	nNumIG = 0;
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone( *pNode, tvTime ))
		if (CExportNel::isMesh( *pNode, tvTime ) || CExportNel::isDummy(*pNode, tvTime))
		{
			aIGArray[nNumIG].DontAddToScene = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_DONT_ADD_TO_SCENE, 0)?true:false;
			aIGArray[nNumIG].InstanceName = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_INSTANCE_NAME, "");
			resultInstanceNode[nNumIG] = pNode;
			if (aIGArray[nNumIG].InstanceName == "") // no instance name was set, takes the node name instead
			{
				aIGArray[nNumIG].InstanceName = pNode->GetName();
			}

			// Visible? always true, but if special flag for camera collision
			sint	appDataCameraCol= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_CAMERA_COLLISION_MESH_GENERATION, 0);
			aIGArray[nNumIG].Visible= appDataCameraCol!=3;


			INode *pParent = pNode->GetParentNode();

			// Set the DontCastShadow flag.
			aIGArray[nNumIG].DontCastShadow= pNode->CastShadows()==0;

			// Set the Special DontCastShadow flag.
			aIGArray[nNumIG].DontCastShadowForInterior= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_LIGHT_DONT_CAST_SHADOW_INTERIOR, BST_UNCHECKED)?true:false;
			aIGArray[nNumIG].DontCastShadowForExterior= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_LIGHT_DONT_CAST_SHADOW_EXTERIOR, BST_UNCHECKED)?true:false;

			// Is the pNode has the root node for parent ?
			if( pParent->IsRootNode() == 0 )
			{
				// Look if the parent is in the selection
				int nNumIG2 = 0;
				for (j = 0; j < vectNode.size(); ++j)
				{
					INode *pNode2 = vectNode[j];

					int nAccelType2 = CExportNel::getScriptAppData (pNode2, NEL3D_APPDATA_ACCEL, 32);
					if ((nAccelType2&3) == 0) // If not an accelerator
					if (!RPO::isZone( *pNode2, tvTime ))
					if (CExportNel::isMesh( *pNode2, tvTime ))
					{
						if (pNode2 == pParent)
							break;
						++nNumIG2;
					}
				}
				if (nNumIG2 == nNbInstance)
				{
					// The parent is not selected ! link to root
					aIGArray[nNumIG].nParent = -1;
				}
				else
				{
					aIGArray[nNumIG].nParent = nNumIG2;
				}
			}
			else
			{
				aIGArray[nNumIG].nParent = -1;
			}
			++nNumIG;
		}
	}
	aIGArray.resize( nNumIG );
	resultInstanceNode.resize( nNumIG );

	// Build the array of node
	vGlobalPos = CVector(0,0,0);
	nNumIG = 0;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh (*pNode, tvTime) || CExportNel::isDummy(*pNode, tvTime))
		{
			CVector vScaleTemp;
			CQuat qRotTemp;
			CVector vPosTemp;

			// Get Nel Name for the object.
			aIGArray[nNumIG].Name= CExportNel::getNelObjectName(*pNode);

			//Get the local transformation matrix
			Matrix3 nodeTM = pNode->GetNodeTM(0);
			INode *pParent = pNode->GetParentNode();
			Matrix3 parentTM = pParent->GetNodeTM(0);
			Matrix3 localTM	= nodeTM*Inverse(parentTM);

			// Extract transformations
			CExportNel::decompMatrix (vScaleTemp, qRotTemp, vPosTemp, localTM);
			aIGArray[nNumIG].Rot   = qRotTemp;
			aIGArray[nNumIG].Pos   = vPosTemp;
			aIGArray[nNumIG].Scale = vScaleTemp;
			vGlobalPos += vPosTemp;
			++nNumIG;
		}
	}
	// todo Make this work (precision):
	/*
	vGlobalPos = vGlobalPos / nNumIG;
	for (i = 0; i < nNumIG; ++i)
		aIGArray[i].Pos -= vGlobalPos;
	*/

	vGlobalPos = CVector(0,0,0); // Temporary !!!

	// Accelerator Portal/Cluster part
	//=================

	// Creation of all the clusters
	vector<CCluster> vClusters;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, NEL3D_APPDATA_ACCEL_DEFAULT);
		bool bFatherVisible = nAccelType&NEL3D_APPDATA_ACCEL_FATHER_VISIBLE?true:false;
		bool bVisibleFromFather = nAccelType&NEL3D_APPDATA_ACCEL_VISIBLE_FROM_FATHER?true:false;
		bool bAudibleLikeVisible = (nAccelType&NEL3D_APPDATA_ACCEL_AUDIBLE_NOT_LIKE_VISIBLE)?false:true;
		bool bFatherAudible = bAudibleLikeVisible ? bFatherVisible : nAccelType&NEL3D_APPDATA_ACCEL_FATHER_AUDIBLE?true:false;
		bool bAudibleFromFather = bAudibleLikeVisible ? bVisibleFromFather : nAccelType&NEL3D_APPDATA_ACCEL_AUDIBLE_FROM_FATHER?true:false;

		if ((nAccelType&NEL3D_APPDATA_ACCEL_TYPE) == NEL3D_APPDATA_ACCEL_CLUSTER) // If cluster
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh(*pNode, tvTime))
		{
			CCluster clusterTemp;
			std::string temp;

			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_SOUND_GROUP, "no sound");
			clusterTemp.setSoundGroup(temp != "no sound" ? temp : "");
			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_ENV_FX, "no fx");
			clusterTemp.setEnvironmentFx(temp != "no fx" ? temp : "");

			CMesh::CMeshBuild *pMB;
			CMeshBase::CMeshBaseBuild *pMBB;
			pMB = createMeshBuild (*pNode, tvTime, pMBB);

			convertToWorldCoordinate( pMB, pMBB );

			for (j = 0; j < pMB->Faces.size(); ++j)
			{
				if (!clusterTemp.makeVolume (pMB->Vertices[pMB->Faces[j].Corner[0].Vertex],
											 pMB->Vertices[pMB->Faces[j].Corner[1].Vertex],
											 pMB->Vertices[pMB->Faces[j].Corner[2].Vertex]) )
				{
					// ERROR : The volume is not convex !!!
					char tam[256];
					sprintf(tam,"ERROR: The cluster %s is not convex.",vectNode[i]->GetName());
					//MessageBox(NULL,tam,"Error",MB_OK|MB_ICONERROR);
					nlwarning(tam);
				}
			}

			clusterTemp.FatherVisible = bFatherVisible;
			clusterTemp.VisibleFromFather = bVisibleFromFather;
			clusterTemp.FatherAudible = bFatherAudible;
			clusterTemp.AudibleFromFather = bAudibleFromFather;
			clusterTemp.Name = pNode->GetName();

			vClusters.push_back (clusterTemp);
			delete pMB;
			delete pMBB;
		}
	}

	// Creation of all the portals
	vector<CPortal> vPortals;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 1) // If Portal
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh(*pNode, tvTime))
		{
			CPortal portalTemp;
			std::string temp;

			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_OCC_MODEL, "no occlusion");
			portalTemp.setOcclusionModel(temp != "no occlusion" ? temp : "");
			temp = CExportNel::getScriptAppData(pNode, NEL3D_APPDATA_OPEN_OCC_MODEL, "no occlusion");
			portalTemp.setOpenOcclusionModel(temp != "no occlusion" ? temp : "");

			CMesh::CMeshBuild *pMB;
			CMeshBase::CMeshBaseBuild *pMBB;
			pMB = createMeshBuild (*pNode, tvTime, pMBB);

			convertToWorldCoordinate( pMB, pMBB );

			vector<sint32> poly;
			vector<bool> facechecked;
			facechecked.resize (pMB->Faces.size());
			for (j = 0; j < pMB->Faces.size(); ++j)
				facechecked[j] = false;

			poly.push_back(pMB->Faces[0].Corner[0].Vertex);
			poly.push_back(pMB->Faces[0].Corner[1].Vertex);
			poly.push_back(pMB->Faces[0].Corner[2].Vertex);
			facechecked[0] = true;
			for (j = 0; j < pMB->Faces.size(); ++j)
			if (!facechecked[j])
			{
				bool found = false;

				for(k = 0; k < 3; ++k)
				{
					for(m = 0; m < poly.size(); ++m)
					{
						if ((pMB->Faces[j].Corner[k].Vertex == poly[m]) &&
							(pMB->Faces[j].Corner[(k+1)%3].Vertex == poly[(m+1)%poly.size()]))
						{
							found = true;
							break;
						}
						if ((pMB->Faces[j].Corner[(k+1)%3].Vertex == poly[m]) &&
							(pMB->Faces[j].Corner[k].Vertex == poly[(m+1)%poly.size()]))
						{
							found = true;
							break;
						}
					}
					if (found)
						break;
				}
				if (found)
				{
					// insert an empty space in poly between m and m+1
					poly.resize (poly.size()+1);
					for (uint32 a = poly.size()-2; a > m; --a)
						poly[a+1] = poly[a];
					poly[m+1] = pMB->Faces[j].Corner[(k+2)%3].Vertex;
					facechecked[j] = true;
					j = 0;
				}
			}
			vector<CVector> polyv;
			polyv.resize (poly.size());
			for (j = 0; j < poly.size(); ++j)
				polyv[j] = pMB->Vertices[poly[j]];
			
			if (!portalTemp.setPoly (polyv))
			{
				// ERROR : Poly not convex, or set of vertices not plane
				char tam[256];
				sprintf(tam,"ERROR: The portal %s is not convex.",vectNode[i]->GetName());
				//MessageBox(NULL,tam,"Error",MB_OK|MB_ICONERROR);
				nlwarning(tam);
			}

			if (nAccelType&16) // is dynamic portal ?
			{
				string InstanceName = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_INSTANCE_NAME, "");
				if (!InstanceName.empty())
					portalTemp.setName (InstanceName);
				else
					portalTemp.setName (string(pNode->GetName()));
			}

			// Check if portal has 2 cluster
			int nNbCluster = 0;
			for (j = 0; j < vClusters.size(); ++j)
			{
				bool bPortalInCluster = true;
				for (k = 0; k < polyv.size(); ++k)
					if (!vClusters[j].isIn (polyv[k]) )
					{
						bPortalInCluster = false;
						break;
					}
				if (bPortalInCluster)
					++nNbCluster;
			}
			if (nNbCluster != 2)
			{
				// ERROR
				char tam[256];
				sprintf(tam,"ERROR: The portal %s has not 2 clusters but %d",vectNode[i]->GetName(), nNbCluster);
				//MessageBox(NULL,tam,"Error",MB_OK|MB_ICONERROR);
				nlwarning(tam);
			}


			vPortals.push_back (portalTemp);
			delete pMB;
			delete pMBB;
		}
	}

	// Link instance to clusters (an instance has a list of clusters)
	nNumIG = 0;
	it = vectNode.begin();
	for (i = 0; i < (sint)vectNode.size(); ++i, ++it)
	{
		INode *pNode = *it;

		int nAccelType = CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_ACCEL, 32);

		if ((nAccelType&3) == 0) // If not an accelerator
		if (!RPO::isZone (*pNode, tvTime))
		if (CExportNel::isMesh (*pNode, tvTime) || CExportNel::isDummy(*pNode, tvTime))
		{
			if (nAccelType&32) // Is the flag clusterize set ?
			{
				// Test against all clusters

				// The list of vertices used to test against cluster
				std::vector<NLMISC::CVector> *testVertices;
				std::vector<NLMISC::CVector>       FXVertices;  // Used only if the obj is a fx. It contains the corners of the bbox.
				bool  buildMeshBBox = true;

				/** If it is a mesh, we build its bbox and transform in world
				  * If it is a FX, we read its bbox from its shape
				  * If we can't read it, we use the bbox of the fx helper in max
				  */
				Object *obj = pNode->EvalWorldState(tvTime).obj;
				// Check if there is an object
				if (obj)
				{
					Class_ID  clid = obj->ClassID();
					// is the object a particle system ?					
					if (clid.PartA() == NEL_PARTICLE_SYSTEM_CLASS_ID)
					{
						// build the shape from the file name
						std::string objName = CExportNel::getNelObjectName(*pNode); 						
						if (!objName.empty())
						{											
							NL3D::CShapeStream ss;
							NLMISC::CIFile iF;
							if (iF.open(objName.c_str()))
							{
								try
								{								
									iF.serial(ss);
									NL3D::CParticleSystemShape *pss = dynamic_cast<NL3D::CParticleSystemShape *>(ss.getShapePointer());
									if (!pss)
									{
										nlwarning("ERROR: Node %s shape is not a FX", CExportNel::getName(*pNode).c_str());
									}
									else
									{									
										NLMISC::CAABBox bbox;
										pss->getAABBox(bbox);
										// transform in world
										Matrix3 xForm = pNode->GetNodeTM(tvTime);
										NLMISC::CMatrix nelXForm;
										CExportNel::convertMatrix(nelXForm, xForm);									
										bbox = NLMISC::CAABBox::transformAABBox(nelXForm, bbox);
										// store vertices of the bbox in the list
										FXVertices.reserve(8);
										for(uint k = 0; k < 8; ++k)
										{
											FXVertices.push_back(CVector(((k & 1) ? 1 : -1) * bbox.getHalfSize().x + bbox.getCenter().x,
																		 ((k & 2) ? 1 : -1) * bbox.getHalfSize().y + bbox.getCenter().y,
																		 ((k & 4) ? 1 : -1) * bbox.getHalfSize().z + bbox.getCenter().z));
										}
										//
										testVertices = &FXVertices;
										buildMeshBBox = false;
									}
									delete ss.getShapePointer();
								}
								catch (NLMISC::Exception &e)
								{
									nlwarning(e.what());									
								}
							}							
							if (buildMeshBBox)
							{
								nlwarning("ERROR: Can't get bbox of a particle system from its shape, using helper bbox instead");
							}
						}
					}
				}

				CMesh::CMeshBuild *pMB = NULL;
				CMeshBase::CMeshBaseBuild *pMBB = NULL;

				if (buildMeshBBox)
				{				
					pMB = createMeshBuild (*pNode, tvTime, pMBB);
					convertToWorldCoordinate( pMB, pMBB );
					testVertices = &pMB->Vertices;
				}

				for(k = 0; k < vClusters.size(); ++k)
				{
					bool bMeshInCluster = false;

					for(j = 0; j < testVertices->size(); ++j)
					{
						if (vClusters[k].isIn ((*testVertices)[j]))
						{
							bMeshInCluster = true;
							break;
						}
					}

					if (bMeshInCluster)
					{
						aIGArray[nNumIG].Clusters.push_back (k);
					}
				}
				
				// debug purpose : to remove
				if (vClusters.size() > 0)
				if (aIGArray[nNumIG].Clusters.size() == 0)
				{
					char tam[256];
					sprintf(tam,"ERROR: Object %s is not attached to any cluster\nbut his flag clusterize is set", pNode->GetName());
					//MessageBox(NULL, tam, "Warning", MB_OK);
					nlwarning(tam);
				}
				// debug purpose : to remove

				delete pMB;
				delete pMBB;
			}
			
			++nNumIG;
		}
		// debug purpose : to remove
		/*
		if ((nAccelType&3) == 0) // If not an accelerator
		if (!(nAccelType&32))
		{
			char tam[256];
			sprintf(tam,"Object %s is not clusterized", pNode->GetName());
			MessageBox(NULL, tam, "Info", MB_OK);
		}
		*/
		// debug purpose : to remove

	}


	// PointLight part
	//=================
	bool	sunLightEnabled= false;
	sint	nNumPointLight = 0;
	vector<CPointLightNamed>	pointLights;
	pointLights.resize(vectNode.size());
	// For all nodes
	for (i = 0; i < (sint)vectNode.size(); ++i)
	{
		INode *pNode = vectNode[i];

		SLightBuild		sLightBuild;

		// If it is a Max Light.
		if ( sLightBuild.canConvertFromMaxLight(pNode, tvTime) )
		{
			// And if this light is checked to realtime export
			int		nRTExport= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_EXPORT_REALTIME_LIGHT, BST_CHECKED);
			if(nRTExport == BST_CHECKED)
			{
				// get Max Light info.
				sLightBuild.convertFromMaxLight(pNode, tvTime);

				// Skip if LightDir
				if(sLightBuild.Type != SLightBuild::LightDir)
				{
					// Fill PointLight Info.
					NL3D::CPointLightNamed	&plNamed= pointLights[nNumPointLight];

					// Position
					plNamed.setPosition(sLightBuild.Position);
					// Attenuation
					plNamed.setupAttenuation(sLightBuild.rRadiusMin, sLightBuild.rRadiusMax);
					// Colors
					// Ensure A=255 for localAmbient to work.
					NLMISC::CRGBA	ambient= sLightBuild.Ambient;
					ambient.A= 255;
					plNamed.setDefaultAmbient(ambient);
					plNamed.setAmbient(ambient);
					plNamed.setDefaultDiffuse(sLightBuild.Diffuse);
					plNamed.setDiffuse(sLightBuild.Diffuse);
					plNamed.setDefaultSpecular(sLightBuild.Specular);
					plNamed.setSpecular(sLightBuild.Specular);

					// GroupName.
					plNamed.AnimatedLight = sLightBuild.AnimatedLight;
					plNamed.LightGroup = sLightBuild.LightGroup;

					// Which light type??
					if(sLightBuild.bAmbientOnly || sLightBuild.Type== SLightBuild::LightAmbient)
					{
						plNamed.setType(CPointLight::AmbientLight);
						// Special ambient info
						int		nRTAmbAdd= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_REALTIME_AMBIENT_ADD_SUN, BST_UNCHECKED);
						plNamed.setAddAmbientWithSun(nRTAmbAdd==BST_CHECKED);
					}
					else if(sLightBuild.Type== SLightBuild::LightPoint)
					{
						plNamed.setType(CPointLight::PointLight);
					}
					else if(sLightBuild.Type== SLightBuild::LightSpot)
					{
						plNamed.setType(CPointLight::SpotLight);
						// Export Spot infos.
						plNamed.setupSpotDirection(sLightBuild.Direction);
						plNamed.setupSpotAngle(sLightBuild.rHotspot, sLightBuild.rFallof);
					}
					else
					{
						// What???
						nlstop;
					}


					// inc Size
					++nNumPointLight;
				}
			}

			// if this light is a directionnal and checked to export as Sun Light
			int		nExportSun= CExportNel::getScriptAppData (pNode, NEL3D_APPDATA_EXPORT_AS_SUN_LIGHT, BST_UNCHECKED);
			if(nExportSun== BST_CHECKED)
			{
				// get Max Light info.
				sLightBuild.convertFromMaxLight(pNode, tvTime);

				// Skip if not dirLight.
				if(sLightBuild.Type == SLightBuild::LightDir)
					sunLightEnabled= true;
			}
		}
	}
	// Good size
	pointLights.resize(nNumPointLight);


	// Build the ig
	//=================

	CInstanceGroup* pIG = new CInstanceGroup;

	// Link portals and clusters and create meta cluster if one
	pIG->build (vGlobalPos,  aIGArray, vClusters, vPortals, pointLights);

	// IG touched by sun ??
	pIG->enableRealTimeSunContribution(sunLightEnabled);

	return pIG;
}
Exemplo n.º 5
0
void ClustererDBSCAN::run_cluster(Points samples)
{

        ClusterId cid = 1;
        // foreach pid
        for (PointId pid = 0; pid < samples.size(); pid++)
        {
                // not already visited
                if (!_visited[pid]){

                        _visited[pid] = true;

                        // get the neighbors
                        Neighbors ne = findNeighbors(pid, _eps);

                        // not enough support -> mark as noise
                        if (ne.size() < _minPts)
                        {
                                _noise[pid] = true;
                        }
                        else
                        {
                            //else it's a core point
                                _core[pid] = true;

                                // Add p to current cluster

                                CCluster c;              // a new cluster
                                c.push_back(pid);   	// assign pid to cluster
                                _pointId_to_clusterId[pid]=cid;

                                // go to neighbors
                                for (unsigned int i = 0; i < ne.size(); i++)
                                {
                                        PointId nPid = ne[i];

                                        // not already visited
                                        if (!_visited[nPid])
                                        {
                                                _visited[nPid] = true;

                                                // go to neighbors
                                                Neighbors ne1 = findNeighbors(nPid, _eps);

                                                // enough support
                                                if (ne1.size() >= _minPts)
                                                {
                                                        _core[nPid] = true;

                                                        // join
                                                        BOOST_FOREACH(Neighbors::value_type n1, ne1)
                                                        {
                                                                // join neighbord
                                                                ne.push_back(n1);    
                                                        }
                                                }
                                        }

                                        // not already assigned to a cluster
                                        if (!_pointId_to_clusterId[nPid])
                                        {
                                            // add it to the current cluster
                                                c.push_back(nPid);
                                                _pointId_to_clusterId[nPid]=cid;
                                        }
                                }
Exemplo n.º 6
0
// ***************************************************************************
CInstanceGroup *CScene::findCameraClusterSystemFromRay(CInstanceGroup *startClusterSystem,
											   const NLMISC::CVector &startPos, NLMISC::CVector &endPos)
{
	CInstanceGroup	*resultCS= NULL;

	CClipTrav	&clipTrav= getClipTrav();

	// **** Search all cluster where the startPos is in
	static vector<CCluster*> vCluster;
	vCluster.clear();

	bool bInWorld = true;
	clipTrav.Accel.select (startPos, startPos);
	CQuadGrid<CCluster*>::CIterator itAcc = clipTrav.Accel.begin();
	while (itAcc != clipTrav.Accel.end())
	{
		CCluster *pCluster = *itAcc;
		if( pCluster->Group == startClusterSystem &&
			pCluster->isIn (startPos) )
		{
			vCluster.push_back (pCluster);
			bInWorld = false;
		}
		++itAcc;
	}
	if (bInWorld)
	{
		vCluster.push_back (RootCluster);
	}

	// **** Do a traverse starting from each start cluser, clipping the ray instead of the camera pyramid
	uint	i;
	static vector<CCluster*> vClusterVisited;
	vClusterVisited.clear();
	for(i=0;i<vCluster.size();i++)
	{
		vCluster[i]->cameraRayClip(startPos, endPos, vClusterVisited);
	}

	// **** From each cluster, select possible clusterSystem
	static vector<CInstanceGroup*> possibleClusterSystem;
	possibleClusterSystem.clear();
	for(i=0;i<vClusterVisited.size();i++)
	{
		// select only cluster where the EndPos lies in. Important else in landscape, we'll always say
		// that we are in a Son Cluster.
		if(vClusterVisited[i]->isIn(endPos))
		{
			CInstanceGroup	*cs= vClusterVisited[i]->Group;
			// insert if not exist (NB: 1,2 possible clusterSystem so O(N2) is OK)
			uint	j;
			for(j=0;j<possibleClusterSystem.size();j++)
			{
				if(possibleClusterSystem[j]==cs)
					break;
			}
			if(j==possibleClusterSystem.size())
				possibleClusterSystem.push_back(cs);
		}
	}

	// If no cluster found, then we may be in a "Data Error case".
	// In this case, ensure the Camera position in a cluster
	if(possibleClusterSystem.empty())
	{
		CCluster	*bestCluster= NULL;
		float		shortDist= FLT_MAX;

		for(i=0;i<vClusterVisited.size();i++)
		{
			// if the ray is at least partially in this cluster
			CVector		a= startPos;
			CVector		b= endPos;
			if(vClusterVisited[i]->clipSegment(a, b))
			{
				float	dist= (endPos - b).norm();
				if(dist<shortDist)
				{
					bestCluster= vClusterVisited[i];
					shortDist= dist;
				}
			}
		}

		// if found
		if(bestCluster)
		{
			// append the best one to the possible Cluster System
			possibleClusterSystem.push_back(bestCluster->Group);

			// and modify endPos, so the camera will really lies into this cluster
			const float	threshold= 0.05f;
			shortDist+= threshold;
			// must not goes more than startPos!
			float	rayDist= (startPos - endPos).norm();
			shortDist= min(shortDist, rayDist);
			endPos+= (startPos - endPos).normed() * shortDist;
		}
	}

	// NB: still possible that the possibleClusterSystem is empty, if not in any cluster for instance :)


	// **** From each possible clusterSystem, select the one that is the lower in hierarchy
	// common case
	if(possibleClusterSystem.empty())
		resultCS= NULL;
	else if(possibleClusterSystem.size()==1)
	{
		// if it is the rootCluster set NULL (should have the same behavior but do like standard case)
		if(possibleClusterSystem[0]==RootCluster->getClusterSystem())
			resultCS= NULL;
		// set this cluster system
		else
			resultCS= possibleClusterSystem[0];
	}
	// conflict case
	else
	{
		// compute the hierarchy level of each cluster system, take the highest
		CInstanceGroup	*highest= NULL;
		uint			highestLevel= 0;
		for(i=0;i<possibleClusterSystem.size();i++)
		{
			uint	level= 0;
			CInstanceGroup	*ig= possibleClusterSystem[i];
			while(ig)
			{
				ig= ig->getParentClusterSystem();
				level++;
			}
			if(level>=highestLevel)
			{
				highestLevel= level;
				highest= possibleClusterSystem[i];
			}
		}

		// set the highest cluster system
		resultCS= highest;
	}

	return resultCS;
}