Пример #1
0
void modelShutdown()
{
	for (MODELMAP::iterator i = models.begin(); i != models.end(); i = models.erase(i))
	{
		iV_IMDRelease(i.value());
	}
	models.clear();
}
Пример #2
0
const QString &modelName(iIMDShape *model)
{
	for (MODELMAP::iterator i = models.begin(); i != models.end(); ++i)
	{
		if (i.value() == model)
		{
			return i.key();
		}
	}
	ASSERT(false, "An IMD pointer could not be backtraced to a filename!");
	static QString error;
	return error;
}
//This message is triggered by the cscenevisibility manager.
//It hijacks the visibility list
DWORD CObjectCubeMapManager::OnCheckLODs(DWORD size, void *params)
{
	
	PERFORMANCE_PROFILER_START( CObjectCubeMapManager_OnCheckLODS )
		
	VERIFY_MESSAGE_SIZE(size, sizeof(ADDRENDERLISTPARAMS));

	// extract params
	ADDRENDERLISTPARAMS *arlp;
	arlp = (ADDRENDERLISTPARAMS *)params;
	static DWORD msgHash_AddRenderList = CHashString(_T("AddRenderList")).GetUniqueID();
	if( m_CubeMaps.size() == 0 )
	{
		m_ToolBox->SendMessage(msgHash_AddRenderList, sizeof(*arlp), arlp);
		PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );
		return MSG_HANDLED_PROCEED;
	}

	OBJECTLIST::iterator objIter;
	OBJECTLIST *visibleObjList = NULL;
	OBJECTLIST spriteObjList;
	OBJECTLIST *spriteObjListPtr = NULL;
	IHashString *objName;
	DWORDSET::iterator setIter;
	CHashString modelFileName;
	CUBEMAPMAP::iterator cmIter;
	MODELMAP modelMap;
	MODELMAP::iterator mmIter;
	std::vector<OBJECTLIST::iterator> iteratorsToDelete;
	DWORD index;
	int numModels;
	ADDSPRITELISTMESSAGE aslm;
	Vec3 currentPosition;
	float pos[3];
	int i = 0;
	ChannelDesc channelDesc[2];
	LODSpriteVertex *data = NULL;
	IHashString *pCameraName = NULL;
	Vec3 camPos, vecCamView, vecCamUp, vecCamRight;
	EulerAngle objRotation;
	StdString error;
	Vec3 viewVec, st, uvw, right, up, camView;
	Vec3 upperRight, lowerRight, upperLeft, lowerLeft;
	Vec3 worldUp;
	Vec3 camRight, camUp;	
	CAMERAVECTORSPARAMS camVectors;
	// params for getting the bounding box
	GETBOUNDINGSPHEREPARAMS bSphere;
	Vec3 objPos;
	bSphere.position = &objPos;

	
	// grab the visible object list
	visibleObjList = arlp->objList;

	// go through object list and filter out objects that are sprites
	for (objIter = visibleObjList->begin(); objIter != visibleObjList->end(); ++objIter)
	{
		// get the name of the object
		objName = (*objIter)->GetName();

		// get model file name from the object
		static DWORD msgHash_GetModelFileName = CHashString(_T("GetModelFileName")).GetUniqueID();
		static CHashString hsCal3dType(_T("Cal3DRenderObject"));
		if (m_ToolBox->SendMessage(msgHash_GetModelFileName, sizeof(CHashString), &modelFileName, objName, &hsCal3dType) == MSG_HANDLED)
		{	// see if the name is in the map
			cmIter = m_CubeMaps.find(modelFileName.GetUniqueID());

			// if object is a sprite (in the map)
			if (cmIter != m_CubeMaps.end())
			{
				// see if this model type is in the map
				mmIter = modelMap.find(modelFileName.GetUniqueID());

				// if it is...
				if (mmIter != modelMap.end())
				{
					// grab the object list
					spriteObjListPtr = &mmIter->second;
					// add the sprite to the objectlist in the map
					spriteObjListPtr->push_back((*objIter));
				}
				else
				{
					// otherwise add sprite to new object list
					spriteObjList.push_back((*objIter));
					// add new object list to the map
					modelMap[modelFileName.GetUniqueID()] = spriteObjList;
					// clear the old object list
					spriteObjList.clear();
				}

				// add object iterator to the delete list
				iteratorsToDelete.push_back(objIter);
			}
		}
	}

	// go through delete list and DELETE!
	for (index = 0; index < iteratorsToDelete.size(); ++index)
	{
		// remove from regular visible list
		visibleObjList->erase(iteratorsToDelete[index]);
	}
	// clear the delete list since we are done with it
	iteratorsToDelete.clear();

	
	// get active camera name
	CHashString hszCameraName;
	CONTEXTCAMPARAMS ccp;
	ccp.pRC = NULL;
	ccp.szCameraName = &hszCameraName;
	static DWORD msgHash_GetActiveCamera = CHashString(_T("GetActiveCamera")).GetUniqueID();
	if (m_ToolBox->SendMessage(msgHash_GetActiveCamera, sizeof(CONTEXTCAMPARAMS), &ccp ) != MSG_HANDLED)
	{
		// log error
		error = _T("Camera not found.\n");
		m_ToolBox->SetErrorValue(WARN_OBJECT_NOT_FOUND);
		m_ToolBox->Log(LOGWARNING, error);
		PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );
		return false; // no camera
	}
	pCameraName = ccp.szCameraName;

	// get the camera's position
	static DWORD msgHash_GetGlobalPosition = CHashString(_T("GetGlobalPosition")).GetUniqueID();
	if (m_ToolBox->SendMessage(msgHash_GetGlobalPosition, sizeof(Vec3), &camPos, pCameraName,
		&m_ccamTypeName) != MSG_HANDLED)
	{
		// log error
		error = _T("Could not retrieve origin of the active camera.\n");
		m_ToolBox->SetErrorValue(WARN_OBJECT_NOT_FOUND);
		m_ToolBox->Log(LOGWARNING, error);
		PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );
		return false;
	}

	// get camera basis vectors
	camVectors.vViewVector = &vecCamView;
	camVectors.vUpVector = &vecCamUp;
	camVectors.vRightVector = &vecCamRight;
	static DWORD msgHash_GetCameraVectors = CHashString(_T("GetCameraVectors")).GetUniqueID();
	if (m_ToolBox->SendMessage(msgHash_GetCameraVectors, sizeof(camVectors), &camVectors, 
		pCameraName, &m_ccamTypeName ) != MSG_HANDLED)
	{
		// log error
		StdString error;
		error = _T("Error retrieving camera vectors.\n");
		m_ToolBox->SetErrorValue(WARN_OBJECT_NOT_FOUND);
		m_ToolBox->Log(LOGWARNING, error);
		PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );
		return false;
	}

	camUp.Set(vecCamUp.x, vecCamUp.y, vecCamUp.z);
	camUp.Normalize();

	/*
	// get camera view vector
	viewVec.Set(vecCamView.x,vecCamView.y, vecCamView.z);

	// invert it
	viewVec.x = -viewVec.x;
	viewVec.y = -viewVec.y;
	viewVec.z = -viewVec.z;
	*/

	camView.Set(vecCamView.x,vecCamView.y, vecCamView.z);

	// invert it
	camView.x = -camView.x;
	camView.y = -camView.y;
	camView.z = -camView.z;


	/*
	// determine the major axis by finding the largest component of the camera look vector
	if (fabs(camView.x) > fabs(camView.y))
	{
		largest = camView.x;
		ma = CUBEMAP_FACE_X;
	}
	else
	{
		largest = camView.y;
		ma = CUBEMAP_FACE_Y;
	}
	
	if (fabs(largest) < fabs(camView.z))
	{
		largest = camView.z;
		ma = CUBEMAP_FACE_Z;
	}

	if (largest < 0)
	{
		ma++;
	}
	
	// compute the right vector  right = up x look
	right.x	= camUp.y*camView.z-camUp.z*camView.y;
	right.y	= camUp.z*camView.x-camUp.x*camView.z;
	right.z	= camUp.x*camView.y-camUp.y*camView.x;

	// normalize right vector
	right.Normalize();

	// compute the up vector up = look x right
	up.x = camView.y*right.z-camView.z*right.y;
	up.y = camView.z*right.x-camView.x*right.z;
	up.z = camView.x*right.y-camView.y*right.x;
	*/

	// go through the sprites
	for (mmIter = modelMap.begin(); mmIter != modelMap.end(); ++mmIter)
	{
		// grab sprite object list
		spriteObjListPtr = &mmIter->second;
		// find out how many models of this type we have
		numModels = spriteObjListPtr->size();
		// calculate the number of vertices needs
		aslm.m_numVertices = numModels * 6;
		// allocate vertices
		data = new LODSpriteVertex[aslm.m_numVertices];

		// reset i
		i = 0;

		// go through models in the list
		for(objIter = spriteObjListPtr->begin(); objIter != spriteObjListPtr->end(); ++objIter)
		{ 
			// get the name of the object
			objName = (*objIter)->GetParentName();

			// Get the current position of the object
			static DWORD msgHash_GetGlobalPosition = CHashString(_T("GetGlobalPosition")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_GetGlobalPosition, sizeof(Vec3), &currentPosition, objName );

			float distance = sqrt((currentPosition.x - camPos.x)*
				                  (currentPosition.x - camPos.x) +
								  (currentPosition.y - camPos.y)*
								  (currentPosition.y - camPos.y) +
								  (currentPosition.z - camPos.z)*
								  (currentPosition.z - camPos.z));

			if (distance < m_fFadeDistance)
			{
				continue;
			}

			static CHashString hsRenderObjectType(_T("Cal3DRenderObject"));

			// get the bounding box for the object
			static DWORD msgHash_GetBoundingSphere = CHashString(_T("GetBoundingSphere")).GetUniqueID();
			if (m_ToolBox->SendMessage(msgHash_GetBoundingSphere, sizeof(bSphere), &bSphere, objName, &hsRenderObjectType ) != MSG_HANDLED)
			{
				// log error
				error = _T("Cannot retrieve boundingsphere for ");
				error += objName->GetString();
				error += _T("\n");
				m_ToolBox->SetErrorValue(WARN_OBJECT_NOT_FOUND);
				m_ToolBox->Log(LOGWARNING, error);
				PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );
				return MSG_ERROR;
			}

			// get the rotation for the object
			static DWORD msgHash_GetGlobalEuler = CHashString(_T("GetGlobalEuler")).GetUniqueID();
			if (m_ToolBox->SendMessage(msgHash_GetGlobalEuler, sizeof(EulerAngle), &objRotation, objName) != MSG_HANDLED)
			{
				PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );
				return MSG_ERROR;
			}

			// get position values
			pos[0] = currentPosition.x;
			pos[1] = currentPosition.y;
			pos[2] = currentPosition.z;

			// compute vector from the camera to the center of the object
			// swapt z,y for Vision->Cube space
#if 1
			viewVec.x = camPos.x - pos[0];
			viewVec.y = camPos.y - pos[1];
			viewVec.z = camPos.z - pos[2];

			/// TESTING ONLY - NO ONE PANIC!
			Vec3 view(viewVec.x, viewVec.z, viewVec.y);
			Matrix3x3 rotMat;
			MathUtil math;
			math.EulerToMatrix(objRotation, rotMat);

			view *= rotMat;

			Vec3 newViewVec;
			newViewVec.x = view.x;
			newViewVec.y = view.z;
			newViewVec.z = view.y;
			newViewVec.Normalize();
			////////////////////////////////
#else
			//viewVec.x = pos[0] - camPos.x;
			//viewVec.z = pos[1] - camPos.y;
			//viewVec.y = pos[2] - camPos.z;

			GetCubeVector(CUBEMAP_FACE_NEGATIVE_Z, 64, 64, IMAGE_SIZE, IMAGE_SIZE, &viewVec);
#endif
			viewVec.Normalize();

			GetSTCoordinates(&newViewVec, &st);
			st.x *= IMAGE_SIZE;
			st.y *= IMAGE_SIZE;
			st.x -= .5f;
			st.y -= .5f;

			// clamp coordinates
			st.x = MIN((float)FLOOR(st.x+0.5f), IMAGE_SIZE);
			st.y = MIN((float)FLOOR(st.y+0.5f), IMAGE_SIZE);
			st.x = MAX(st.x, 0);
			st.x = MAX(st.x, 0);

			// construct 6 verts with different uvs, all with center position. 
			Vec3 center(pos[0], pos[1], pos[2]);

			switch ((DWORD)st.z) 
			{
				case CUBEMAP_FACE_Z:
					worldUp.Set(0.0f, 0, -1.0f);
					break;
				case CUBEMAP_FACE_NEGATIVE_Z:
					worldUp.Set(0.0f, 0, 1.0f);
					break;
				default:
					worldUp.Set(0.0f,-1.0f, 0);
					break;
			}

			// compute camera right vector using our world up vector and the camera look vector
			camRight.x	= worldUp.y*viewVec.y-worldUp.z*viewVec.z;
			camRight.y	= worldUp.z*viewVec.x-worldUp.x*viewVec.y;
			camRight.z	= worldUp.x*viewVec.z-worldUp.y*viewVec.x;

			// compute new camera up vector using the camera right vector and the camera look vector
			camUp.x	= camRight.y*viewVec.y-camRight.z*viewVec.z;
			camUp.y	= camRight.z*viewVec.x-camRight.x*viewVec.y;
			camUp.z	= camRight.x*viewVec.z-camRight.y*viewVec.x;

			// compute the right vector  right = up x look
			right.x	= camUp.y*viewVec.y-camUp.z*viewVec.z;
			right.y	= camUp.z*viewVec.x-camUp.x*viewVec.y;
			right.z	= camUp.x*viewVec.z-camUp.y*viewVec.x;

			// normalize right vector
			right.Normalize();

			// compute the up vector up = look x right
			up.x = viewVec.z*right.z-viewVec.y*right.y;
			up.y = viewVec.y*right.x-viewVec.x*right.z;
			up.z = viewVec.x*right.y-viewVec.z*right.x;
			
			// compute the size of the sprite (height of the object + a percentage of the height)
			float size = bSphere.radius * 4.0f; //+ (bbox.dimZ * 0.25f);

			// corners of the sprite
			upperRight = center + right*size + up*size;
			upperLeft = center - right*size + up*size;
			lowerRight = center + right*size - up*size;
			lowerLeft = center - right*size - up*size;

			// compute verticies
			data[i*6].pos[0] = lowerLeft.x; //pos[0]-5;
			data[i*6].pos[1] = lowerLeft.y; //pos[1];
			data[i*6].pos[2] = lowerLeft.z; //pos[2]-5;
			uvw.x = (float)((int)(st.x / TILE_SIZE) * TILE_SIZE);
			uvw.y = (float)((int)((st.y + TILE_SIZE) / TILE_SIZE) * TILE_SIZE);
			GetCubeVector( (DWORD)st.z, uvw.x, uvw.y, IMAGE_SIZE, IMAGE_SIZE, &uvw );
			data[i*6].u = uvw.x;
			data[i*6].v = uvw.y;
			data[i*6].w = uvw.z;
			
			data[i*6 + 1].pos[0] = lowerRight.x; //pos[0]+5;
			data[i*6 + 1].pos[1] = lowerRight.y; //pos[1];
			data[i*6 + 1].pos[2] = lowerRight.z; //pos[2]-5;
			uvw.x = (float)((int)((st.x + TILE_SIZE) / TILE_SIZE) * TILE_SIZE);
			uvw.y = (float)((int)((st.y + TILE_SIZE) / TILE_SIZE) * TILE_SIZE);
			GetCubeVector( (DWORD)st.z, uvw.x, uvw.y, IMAGE_SIZE, IMAGE_SIZE, &uvw );
			data[i*6 + 1].u = uvw.x;
			data[i*6 + 1].v = uvw.y;
			data[i*6 + 1].w = uvw.z;

			data[i*6 + 2].pos[0] =  upperLeft.x; //pos[0]-5;
			data[i*6 + 2].pos[1] =  upperLeft.y; //pos[1];
			data[i*6 + 2].pos[2] =  upperLeft.z; //pos[2]+5;
			uvw.x = (float)((int)(st.x / TILE_SIZE) * TILE_SIZE);
			uvw.y = (float)((int)(st.y / TILE_SIZE) * TILE_SIZE);
			GetCubeVector( (DWORD)st.z, uvw.x, uvw.y, IMAGE_SIZE, IMAGE_SIZE, &uvw );
			data[i*6 + 2].u = uvw.x;
			data[i*6 + 2].v = uvw.y;
			data[i*6 + 2].w = uvw.z;
			
			data[i*6 + 3].pos[0] =  upperLeft.x; //pos[0]-5;
			data[i*6 + 3].pos[1] =  upperLeft.y; //pos[1];
			data[i*6 + 3].pos[2] =  upperLeft.z; //pos[2]+5;
			uvw.x = (float)((int)(st.x / TILE_SIZE) * TILE_SIZE);
			uvw.y = (float)((int)(st.y / TILE_SIZE) * TILE_SIZE);
			GetCubeVector( (DWORD)st.z, uvw.x, uvw.y, IMAGE_SIZE, IMAGE_SIZE, &uvw );
			data[i*6 + 3].u = uvw.x;
			data[i*6 + 3].v = uvw.y;
			data[i*6 + 3].w = uvw.z;
			
			data[i*6 + 4].pos[0] =  lowerRight.x; //pos[0]+5;
			data[i*6 + 4].pos[1] =  lowerRight.y; //pos[1];
			data[i*6 + 4].pos[2] =  lowerRight.z; //pos[2]-5;
			uvw.x = (float)((int)((st.x + TILE_SIZE) / TILE_SIZE) * TILE_SIZE);
			uvw.y = (float)((int)((st.y + TILE_SIZE) / TILE_SIZE) * TILE_SIZE);
			GetCubeVector( (DWORD)st.z, uvw.x, uvw.y, IMAGE_SIZE, IMAGE_SIZE, &uvw );
			data[i*6 + 4].u = uvw.x;
			data[i*6 + 4].v = uvw.y;
			data[i*6 + 4].w = uvw.z;
			
			data[i*6 + 5].pos[0] =  upperRight.x; //pos[0]+5;
			data[i*6 + 5].pos[1] =  upperRight.y; //pos[1];
			data[i*6 + 5].pos[2] =  upperRight.z; //pos[2]+5;
			uvw.x = (float)((int)((st.x + TILE_SIZE) / TILE_SIZE) * TILE_SIZE);
			uvw.y = (float)((int)(st.y / TILE_SIZE) * TILE_SIZE);
			GetCubeVector( (DWORD)st.z, uvw.x, uvw.y, IMAGE_SIZE, IMAGE_SIZE, &uvw );
			data[i*6 + 5].u = uvw.x;
			data[i*6 + 5].v = uvw.y;
			data[i*6 + 5].w = uvw.z;
			
			// increment i
			++i;
		}

		// setup descriptor
		channelDesc[0] = MESH_STREAM_VERTEX_POSITION3;
		channelDesc[1] = MESH_STREAM_VERTEX_CUBECOORD1;

		// find the model name in the map of cubemaps
		cmIter = m_CubeMaps.find(mmIter->first);

		if (cmIter == m_CubeMaps.end())
		{
			// something's wrong here
			//TODO: Free up the memory initialized!
			PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );
			return MSG_ERROR;
		}

		// setup message params
		aslm.m_Data = data;
		aslm.m_ChannelDescriptor = channelDesc;
		aslm.m_NumChannels = 2;
		aslm.m_Texture = cmIter->second;
		aslm.m_Effect = m_CubeMapShader;
		
		// make sure our texture and shader are valid
		if (cmIter->second 
			&& m_CubeMapShader)
		{
			// Send data to sprite manager
			static DWORD msgHash_AddSprite = CHashString(_T("AddSprite")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_AddSprite, sizeof(aslm), &aslm);
		}

		// delete data
		if (data)
		{
			delete [] data;
			data = NULL;
		}
	}

	PERFORMANCE_PROFILER_STOP( CObjectCubeMapManager_OnCheckLODS );

	return MSG_HANDLED_PROCEED;
}