Exemplo n.º 1
0
void VCoronaManager::RenderCorona (VCoronaCandidate& coronaCandidate, VTextureObject*& pTexture)
{
#ifdef SUPPORTS_CORONAS
  VCoronaComponent *pCorona = coronaCandidate.m_pCorona;
  VisRenderContext_cl* pContext = VisRenderContext_cl::GetCurrentContext();
  VisLightSource_cl* pLight = (VisLightSource_cl*)pCorona->GetOwner();

  hkvVec3 vLightPos(hkvNoInitialization);
  pLight->GetVirtualPosition(vLightPos, pContext);
  hkvVec3 vEyePos(hkvNoInitialization);
  pContext->GetCamera()->GetPosition(vEyePos);
  hkvVec3 vDir = pContext->GetCamera()->GetDirection();

  // Corona texture
  VTextureObject *pTex = pCorona->GetCoronaTexture();
  if (pTex == NULL)
    return;

  if (pTexture != pTex)
  {
    pTexture = pTex;
    Vision::RenderLoopHelper.BindMeshTexture(pTexture,0);
  }

  // Get light color
  VColorRef color = pLight->GetColor();
  hkvVec3 vDist = vLightPos - vEyePos;
  float fEyeDist = vDir.dot(vDist);

  //determine if camera is in light cone if the light is directional
  float fDirectionalDampening = 1.0f;
  if ( pLight->GetType() == VIS_LIGHT_SPOTLIGHT && pCorona->GetOnlyVisibleInSpotLight() )
  {
    fDirectionalDampening = 0.0f;
    float fConeAngle = pLight->GetProjectionAngle();
    float fConeLength = pLight->GetRadius();
    hkvVec3 fConeDirection = pLight->GetDirection();
    fConeDirection.normalize();

    hkvVec3 vLightEyeDist = vEyePos - vLightPos;

    //#2 check if the camera is inside the angle of the cone
    float cosinusAngle = (vLightEyeDist/vLightEyeDist.getLength()).dot(fConeDirection);
    float fDegree = hkvMath::acosDeg(cosinusAngle);
    float normRadius = fDegree / (fConeAngle/2.0f);

    if (normRadius < 1.0f)
    {
      //hardcoded falloff. For better performance, we avoid sampling the projection texture here.
      const float fEpsilon = 64.0f/256.0f;
      const float fQuadFactor = 1.0f/fEpsilon - 1.0f;
      fDirectionalDampening = 1.0f / (1.0f + fQuadFactor*normRadius*normRadius);

      // scale the function so that the value is exactly 0.0 at the edge and 1.0 in the center
      fDirectionalDampening = (fDirectionalDampening - fEpsilon) / (1.0f - fEpsilon);  
    }
  }
  // Fog params
  float fFogDampening = 1.0f;
  if (pLight->GetType() != VIS_LIGHT_DIRECTED && Vision::World.IsLinearDepthFogEnabled())
  {  
    const VFogParameters &fog = Vision::World.GetFogParameters();
    float fFogStart = fog.fDepthStart;
    float fFogEnd = fog.fDepthEnd;

    float fFogFactor = (fFogEnd > fFogStart) ? ((fEyeDist - fFogStart) / (fFogEnd - fFogStart)) : 0.f;
    fFogDampening = 1.0f - hkvMath::clamp(fFogFactor, 0.0f, 1.0f);
  }

  // Get corona rotation
  float fRotation = 0.0f;
  hkvVec4 vRotation(1.0f, 0.0f, 0.0f, 1.0f);
  if (pCorona->CoronaFlags & VIS_CORONASCALE_ROTATING)
  { 
    fRotation = hkvMath::mod (fEyeDist * 0.5f, 360.f);

    vRotation.x = hkvMath::cosDeg (fRotation);
    vRotation.y = -hkvMath::sinDeg (fRotation);
    vRotation.z = -vRotation.y;
    vRotation.w = vRotation.x;
  }

  // Texture dimensions
  int iSizeX, iSizeY, depth;
  pTex->GetTextureDimensions(iSizeX, iSizeY, depth);

  hkvVec4 vScale(0.0f, 0.0f, 0.0f, 0.0f);

  int iMainWidth, iMainHeight, iWidth, iHeight;
  pContext->GetSize(iWidth, iHeight);
  VisRenderContext_cl::GetMainRenderContext()->GetSize(iMainWidth, iMainHeight);

  // Preserve texture aspect ratio
  int iTexHeight = pTex->GetTextureHeight();
  int iTexWidth = pTex->GetTextureWidth();

  // Perspective scaling
  // This scaling ensures roughly the same size on 720p as the old implementation.
  vScale.z = iTexWidth * pCorona->CoronaScaling * 0.25f;
  vScale.w = iTexHeight * pCorona->CoronaScaling * 0.25f;

  // Screen-space scaling
  // This scaling ensures roughly the same size on 720p as the old implementation.
  const float fScaleFactor = pCorona->CoronaScaling * iMainHeight / 11.0f;
  vScale.x = ((float)iTexWidth / 128.0f) * fScaleFactor * (float(iWidth) / float(iMainWidth));
  vScale.y = ((float)iTexHeight / 128.0f) * fScaleFactor * (float(iHeight) / float(iMainHeight));
  vScale.x *= 2.0f / iWidth;
  vScale.y *= 2.0f / iHeight;
  
  // Scale by visibility
  if (pCorona->CoronaFlags & VIS_CORONASCALE_VISIBLEAREA)
  {
    vScale.x *= coronaCandidate.m_fCurrentVisibility;
    vScale.y *= coronaCandidate.m_fCurrentVisibility;
    vScale.z *= coronaCandidate.m_fCurrentVisibility;
    vScale.w *= coronaCandidate.m_fCurrentVisibility;
  }

  VCompiledShaderPass* pShader = m_spCoronaTechnique->GetShader(0);
  VShaderConstantBuffer *pVertexConstBuffer = pShader->GetConstantBuffer(VSS_VertexShader);
  // xyz = worldspace position, w = 1.0 if VIS_CORONASCALE_DISTANCE is true, otherwise zero.
  pVertexConstBuffer->SetSingleParameterF("coronaPosition", vLightPos.x, vLightPos.y, vLightPos.z, (pCorona->CoronaFlags & VIS_CORONASCALE_DISTANCE) ? 1.0f : 0.0f);
  // xyz = light color, w = corona visibility.
  pVertexConstBuffer->SetSingleParameterF("coronaColor", color.r/255.0f, color.g/255.0f, color.b/255.0f, coronaCandidate.m_fCurrentVisibility * fFogDampening * fDirectionalDampening);
  // xyzw = 2x2 rotation matrix. float2x2 is not supported in shader model 2, so a float4 is used and multiplication is done manually in the shader.
  pVertexConstBuffer->SetSingleParameterF("coronaRotation", vRotation.x, vRotation.y, vRotation.z, vRotation.w);
  // xy = screen-space scaling. zw = view-space scaling.
  pVertexConstBuffer->SetSingleParameterF("coronaScale", vScale.x, vScale.y, vScale.z, vScale.w);
    
  Vision::RenderLoopHelper.RenderMeshes(pShader, VisMeshBuffer_cl::MB_PRIMTYPE_TRILIST, 0, 2, 6);
#endif
}
Exemplo n.º 2
0
// load a file if we recognize the type.
DWORD CXMLWorldLoader::OnLoadWorldFile(DWORD size, void *params)
{
	CHashString oldVersion = _T("");
	CREATEOBJECTPARAMS cop;
	INITOBJECTPARAMS iop;
	SERIALIZEOBJECTPARAMS sop;
	DWORD retVal;
	IXMLArchive *Archive = NULL;
	DWORD currNode = 0;
	LOADINGUPDATEPARAMS pbp;

	VERIFY_MESSAGE_SIZE(size, sizeof(TCHAR *));
	TCHAR *pFileName = (TCHAR *)params;

	// use both a hashstring and a pointer so that the first iteration of the loop
	// will pass SetParentName a NULL instead of an address of a hashstring
	// hashed to ""
	CHashString hszParentType(_T("CWorld"));
	CHashString hszParentName(_T("World"));
	CHashString hszName(_T(""));
	CHashString hszTypeName(_T(""));
	CHashString streamType(_T("File"));

	// delete previous world root
	DELETEOBJECTPARAMS dop;
	dop.name = &hszParentName;
	static DWORD msgHash_DeleteObject = CHashString(_T("DeleteObject")).GetUniqueID();
	EngineGetToolBox()->SendMessage(msgHash_DeleteObject, sizeof(dop), &dop );
	// delete is ok to fail if no world has been created yet

	// create new world root
	cop.name = &hszParentName;
	cop.parentName = NULL;
	cop.typeName = &hszParentType;
	static DWORD msgHash_CreateObject = CHashString(_T("CreateObject")).GetUniqueID();
	DWORD returnValue = EngineGetToolBox()->SendMessage(msgHash_CreateObject, sizeof(cop), &cop );
	if (returnValue != MSG_HANDLED)
	{
		EngineGetToolBox()->Log(LOGERROR, _T("Failed to create World Root Object\n"));
		return MSG_ERROR;
	}

	CREATEARCHIVE ca;
	ca.streamData = (void *)pFileName;
	ca.mode = STREAM_MODE_READ;
	ca.streamType = &streamType;
#ifdef USEXMLFILESTREAMS
	// call the Archive factory to create an XML archive
	static DWORD msgHash_CreateXMLArchiveStream = CHashString(_T("CreateXMLArchiveStream")).GetUniqueID();
	if (retVal = m_ToolBox->SendMessage(msgHash_CreateXMLArchiveStream, sizeof(CREATEARCHIVE), &ca) != MSG_HANDLED)
#else
	// call the Archive factory to create an XML archive
	static DWORD msgHash_CreateXMLArchive = CHashString(_T("CreateXMLArchive")).GetUniqueID();
	if (retVal = m_ToolBox->SendMessage(msgHash_CreateXMLArchive, sizeof(CREATEARCHIVE), &ca) != MSG_HANDLED)
#endif
	{
		return retVal;
	}

	Archive = dynamic_cast<IXMLArchive *>(ca.archive);
	DWORD numNodes = Archive->GetNumberOfNodes();

	// Deteriminte World Version
	int iWorldNumAttrib = Archive->GetNumAttributes();

	StdString szNodeName;
	Archive->GetNode(szNodeName);
	
	pbp.currentPosition = Archive->GetCurrentNodePosition();
	pbp.totalSize = numNodes;
	// update progress bar
	static DWORD msgHash_LoadingUpdate = CHashString(_T("LoadingUpdate")).GetUniqueID();
	m_ToolBox->SendMessage(msgHash_LoadingUpdate, sizeof(LOADINGUPDATEPARAMS), &pbp);


	// must start with <World>
	if (szNodeName != _T("CWorld"))
	{
		EngineGetToolBox()->SetErrorValue(WARN_INVALID_FILE);
		EngineGetToolBox()->Log(LOGWARNING, _T("Invalid world file %s\n"), pFileName);
		Archive->Close();
		return MSG_ERROR;
	}

	// Version 1.0
	if( iWorldNumAttrib == 1 )
	{
		// read the name of the world
		StdString szName;
		Archive->Read( szName, _T("Name") );
		m_WorldFileVersion = 1.0f;
		static DWORD msgHash_GetFileVersion = CHashString(_T("GetFileVersion")).GetUniqueID();
		DWORD retval = m_ToolBox->SendMessage(msgHash_GetFileVersion, sizeof(IHashString), &oldVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not get world version!"));
			return MSG_ERROR;
		}
		CHashString hszNewVersion = _T("1.0");
		static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
		retval = m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &hszNewVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not set world version!"));
			return MSG_ERROR;
		}
	}
	// Version 1.5
	else if( iWorldNumAttrib == 2 )
	{
		StdString szName;
		Archive->Read( szName, _T("Name") );
		float fileVersion = 0;
		Archive->Read( m_WorldFileVersion, _T("Version") );
		static DWORD msgHash_GetFileVersion = CHashString(_T("GetFileVersion")).GetUniqueID();
		DWORD retval = m_ToolBox->SendMessage(msgHash_GetFileVersion, sizeof(IHashString), &oldVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not get world version!"));
			return MSG_ERROR;
		}
		TCHAR buf[50];
		_stprintf(buf, "%.1f", m_WorldFileVersion);
		CHashString hszNewVersion(buf);
		static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
		retval = m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &hszNewVersion);
		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGERROR, _T("Could not set world version!"));
			return MSG_ERROR;
		}
	}
	// Unknown Version
	else
	{
		EngineGetToolBox()->SetErrorValue(WARN_INVALID_FILE);
		EngineGetToolBox()->Log(LOGWARNING, _T("Invalid world file %s\n"), pFileName);
		Archive->Close();
		static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
		m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
		return MSG_ERROR;
	}

	// failure checks
	bool componentFailed = false;
	int failedDepth = 0;

	float secondsPerFrame = 1 / m_fLoadingUpdateFPS;
	ITimer *timer = EngineGetToolBox()->GetTimer();
	float lastLoadTime = timer->GetRealTime();
	float elapsedTime = 0.0f;

	while (Archive->GetNode(szNodeName))
	{
		int currDepth = Archive->GetDepth();
		if (componentFailed == true)
		{
			// current node is child of failed
			if (currDepth > failedDepth)
			{
				continue;
			}
			// if sibling or uncle, reset comp failed flag
			else
			{
				componentFailed = false;
			}
		}

		hszTypeName.Init( szNodeName.c_str() );

		StdString parentName;
		StdString parentType;
		StdString childType;
		Archive->GotoParentNode( parentType );
		Archive->Read( parentName, _T("Name") );
		if ( parentName != _T("") )
		{
			hszParentName = parentName;
		}
		Archive->ReturnToChildNode( childType );
		if( hszTypeName.GetString() != childType )
		{
			assert( hszTypeName.GetString() == childType );
			static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
			return MSG_ERROR;
		}
		//parentName = Archive->GetParentName();

		StdString szName;
		Archive->Read( szName, _T("Name") );
		hszName.Init( szName.c_str() );

		cop.parentName = &hszParentName;
		cop.typeName = &hszTypeName;
		cop.name = &hszName;
		static DWORD msgHash_CreateObject = CHashString(_T("CreateObject")).GetUniqueID();
		DWORD retval = m_ToolBox->SendMessage(msgHash_CreateObject, sizeof(CREATEOBJECTPARAMS), &cop, NULL, NULL);

		if (retval != MSG_HANDLED)
		{
			m_ToolBox->Log(LOGINFORMATION, _T("World loader: could not create component; skipping children!\n"));
			componentFailed = true;
			failedDepth = Archive->GetDepth();			
			continue;
		}

		// 1.0 -> 1.5 Readjusted scale and position on object by 1000/898
		if( m_WorldFileVersion == 1.0 )
		{
			float fConvert = 1000.0f/898.0f;
			if( hszTypeName.GetUniqueID() == CHashString(_T("CV3ORenderObject")).GetUniqueID() )
			{
				StdString szFileName;
				Vec3 vPosition(0,0,0);
				Vec3 vRotation(0,0,0);
				Vec3 vScaling(0,0,0);

				Archive->Read( szFileName, _T("FileName") );
				
				Archive->Read( vPosition, _T("Position") );
				vPosition.x = ( vPosition.x * fConvert );
				vPosition.y = ( vPosition.y * fConvert );
				vPosition.z = ( vPosition.z * fConvert );
				
				Archive->Read( vRotation, _T("Rotation") );

				Archive->Read( vScaling, _T("Scaling") );
				vScaling.x = ( vScaling.x * fConvert );
				vScaling.y = ( vScaling.y * fConvert );
				vScaling.z = ( vScaling.z * fConvert );

				IArchive *MemArchive;
				CHashString memType(_T("Memory"));

				CREATEARCHIVE caOut;
				caOut.mode = STREAM_MODE_WRITE;
				caOut.streamData = NULL;
				caOut.streamSize = 0;
				caOut.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caOut) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive = caOut.archive;

				MemArchive->Write( szFileName, _T("FileName") );
				MemArchive->Write( vPosition, _T("Position") );
				MemArchive->Write( vRotation, _T("Rotation") );
				MemArchive->Write( vScaling, _T("Scaling") );
		
				CREATESTREAM cs;
				cs.streamData = caOut.streamData;
				cs.streamSize = caOut.streamSize;
				cs.mode = STREAM_MODE_READ;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive->Init(cs.openStream);

				sop.name = &hszName;
				sop.archive = MemArchive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
				
				MemArchive->Close();
			}

			else if( hszTypeName.GetUniqueID() == CHashString(_T("CPhysicsObject")).GetUniqueID() )
			{
				//StdString szDynamics;
				StdString szType;
				StdString szShapeFileName;
				//float fMass;
				//Vec3 vPosition;
				//Vec3 vRotation;
				//Vec3 vScaling;

				//Archive->Read( vPosition, _T("pos") );
				//vPosition.SetX( vPosition.GetX() * fConvert );
				//vPosition.SetY( vPosition.GetY() * fConvert );
				//vPosition.SetZ( vPosition.GetZ() * fConvert );

				//Archive->Read( vRotation, _T("rot") );
				
				//Archive->Read( vScaling, _T("scale") );
				//vScaling.SetX( vScaling.GetX() * fConvert );
				//vScaling.SetY( vScaling.GetY() * fConvert );
				//vScaling.SetZ( vScaling.GetZ() * fConvert );

				//Archive->Read( fMass, _T("mass") );
				Archive->Read( szType, _T("Type") );
				Archive->Read( szShapeFileName, _T("filename") );

				IArchive *MemArchive;
				CHashString memType(_T("Memory"));
				//int size =	sizeof(char) * 256 * 2 + sizeof(float) + sizeof(Vec3) * 3 + 256;
				
				CREATEARCHIVE caOut;
				caOut.mode = STREAM_MODE_WRITE;
				caOut.streamData = NULL;
				caOut.streamSize = 0;
				caOut.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caOut) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive = caOut.archive;

				//MemArchive->Write( vPosition, _T("pos") );
				//MemArchive->Write( vRotation, _T("rot") );
				//MemArchive->Write( vScaling, _T("scale") );
				//MemArchive->Write( fMass, _T("mass") );
				//MemArchive->Write( szDynamics, _T("dynamics") );
				//MemArchive->Write( szShapeFileName, _T("shapeFile") );
				MemArchive->Write( szType, _T("Type") );
				MemArchive->Write( szShapeFileName, _T("filename") );

				CREATESTREAM cs;
				cs.streamData = caOut.streamData;
				cs.streamSize = caOut.streamSize;
				cs.mode = STREAM_MODE_READ;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive->Init(cs.openStream);

				sop.name = &hszName;
				sop.archive = MemArchive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);

				MemArchive->Close();
			}
			else if( hszTypeName.GetUniqueID() == CHashString(_T("CTerrainConfig")).GetUniqueID() )
			{
				StdString szTerShaderLib;
				StdString szTerShaderEff;
				int iSectorRes;
				float fSectorSize;
				float fZScale;
				float fLODDistance;

				Archive->Read( szTerShaderLib, _T("TerrainShaderLibrary") );
				Archive->Read( szTerShaderEff, _T("TerrainShaderEffect") );
				Archive->Read( iSectorRes, _T("SectorResolution") );
				Archive->Read( fSectorSize, _T("SectorSize") );
				fSectorSize = fSectorSize * fConvert;
				Archive->Read( fZScale, _T("ZScale") );
				fZScale = fZScale * fConvert;
				Archive->Read( fLODDistance, _T("LODDistance") );
				
				IArchive *MemArchive;
				CHashString memType(_T("Memory"));
				
				CREATEARCHIVE caOut;
				caOut.mode = STREAM_MODE_WRITE;
				caOut.streamData = NULL;
				caOut.streamSize = 0;
				caOut.streamType = &memType;
				static DWORD msgHash_CreateArchive = CHashString(_T("CreateArchive")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateArchive, sizeof(CREATEARCHIVE), &caOut) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive = caOut.archive;

				MemArchive->Write( szTerShaderLib, _T("TerrainShaderLibrary") );
				MemArchive->Write( szTerShaderEff, _T("TerrainShaderEffect") );
				MemArchive->Write( iSectorRes, _T("SectorResolution") );
				MemArchive->Write( fSectorSize, _T("SectorSize") );
				MemArchive->Write( fZScale, _T("ZScale") );
				MemArchive->Write( fLODDistance, _T("LODDistance") );

				CREATESTREAM cs;
				cs.streamData = caOut.streamData;
				cs.streamSize = caOut.streamSize;
				cs.mode = STREAM_MODE_READ;
				static DWORD msgHash_CreateStream_Memory = CHashString(_T("CreateStream_Memory")).GetUniqueID();
				if (m_ToolBox->SendMessage(msgHash_CreateStream_Memory, sizeof(CREATESTREAM), &cs) != MSG_HANDLED)
				{
					static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
					m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);
					return true;
				}
				MemArchive->Init(cs.openStream);

				sop.name = &hszName;
				sop.archive = MemArchive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);

				MemArchive->Close();
			}
			else
			{
				sop.name = &hszName;
				sop.archive = Archive;
				static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
				m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
			}
		}
		else
		{
			sop.name = &hszName;
			sop.archive = Archive;
			static DWORD msgHash_SerializeObject = CHashString(_T("SerializeObject")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_SerializeObject, sizeof(SERIALIZEOBJECTPARAMS), &sop, NULL, NULL);
		}

		iop.name = &hszName;
		static DWORD msgHash_InitObject = CHashString(_T("InitObject")).GetUniqueID();
		m_ToolBox->SendMessage(msgHash_InitObject, sizeof(INITOBJECTPARAMS), &iop, NULL, NULL);

		elapsedTime += timer->GetRealTime() - lastLoadTime;
		lastLoadTime = timer->GetRealTime();				
		if (elapsedTime > secondsPerFrame)
		{
			elapsedTime = 0.0f;
			pbp.currentPosition = Archive->GetCurrentNodePosition();
			pbp.totalSize = numNodes;
			m_ToolBox->SendMessage(msgHash_LoadingUpdate, sizeof(LOADINGUPDATEPARAMS), &pbp);
		}
	}

	pbp.currentPosition = 0;
	pbp.totalSize = 0;
	m_ToolBox->SendMessage(msgHash_LoadingUpdate, sizeof(LOADINGUPDATEPARAMS), &pbp);

	Archive->Close();

	static DWORD msgHash_SetFileVersion = CHashString(_T("SetFileVersion")).GetUniqueID();
	m_ToolBox->SendMessage(msgHash_SetFileVersion, sizeof(IHashString), &oldVersion);

	return MSG_HANDLED_STOP;
}
Exemplo n.º 3
0
void CIFXMotionDecoder::ProcessMotionCompressedX( IFXDataBlockX &rDataBlockX )
{
	if(NULL == m_pCoreServices) {
		IFXCHECKX(IFX_E_NOT_INITIALIZED);
	}

	// Get the scene graph
	IFXDECLARELOCAL(IFXSceneGraph,pSceneGraph);
	IFXCHECKX(m_pCoreServices->GetSceneGraph( IID_IFXSceneGraph,( void** )&pSceneGraph ));

	// Process the motion description data block
	// The motion description block has the following sections:
	// 1. MotionName
	// 2. TrackCount
	// 3. InverseQuantTime
	// 4. InverseQuantRotation
	//    5. TrackName
	//    6. TimeCount
	//    7. InverseQuantDisplacement
	//    8. InverseQuantScale
	//      9. Time
	//      10. Displacement
	//      11. Rotation
	//      12. Scale

	// set metadata
	IFXDECLARELOCAL(IFXMetaDataX, pBlockMD);
	IFXDECLARELOCAL(IFXMetaDataX, pObjectMD);
	rDataBlockX.QueryInterface(IID_IFXMetaDataX, (void**)&pBlockMD);
	m_pObject->QueryInterface(IID_IFXMetaDataX, (void**)&pObjectMD);
	pObjectMD->AppendX(pBlockMD);

	// Create a bitstream component and initialize it to decode the block
	IFXDECLARELOCAL(IFXBitStreamCompressedX,pBitStreamX);
	IFXCHECKX(IFXCreateComponent( CID_IFXBitStreamX, IID_IFXBitStreamCompressedX, ( void** )&pBitStreamX ));
	IFXDECLARELOCAL(IFXNameMap, pNameMap);
	m_pCoreServices->GetNameMap(IID_IFXNameMap, (void**)&pNameMap);
	U32 uProfile;
	pNameMap->GetProfile(m_uLoadId, uProfile);
	pBitStreamX->SetNoCompressionMode((uProfile & IFXPROFILE_NOCOMPRESSION) ? TRUE : FALSE);

	U32 uBlockType = 0;
	rDataBlockX.GetBlockTypeX(uBlockType);
	pBitStreamX->SetDataBlockX( rDataBlockX );

	// 1. MotionName
	IFXString stringMotionName;
	// read the motion name
	pBitStreamX->ReadIFXStringX( stringMotionName );
	IFXCHECKX(pNameMap->Map(m_uLoadId, IFXSceneGraph::MOTION, stringMotionName));

	// Access the appropriate interface of the shader that was handed in via SetObject().
	IFXDECLARELOCAL(IFXMotionResource,pMotionResource);
	IFXCHECKX(m_pObject->QueryInterface( IID_IFXMotionResource, (void**)&pMotionResource ));

	pMotionResource->GetMotionRef()->SetName(stringMotionName);

	// 2. TrackCount
	U32 uTrackCount = 0;
	pBitStreamX->ReadU32X( uTrackCount );
	// 3. InverseQuantTime
	F32 fInverseQuantTime = 1.0;
	pBitStreamX->ReadF32X( fInverseQuantTime );
	// 4. InverseQuantRotation
	F32 fInverseQuantRotation = 1.0;
	pBitStreamX->ReadF32X( fInverseQuantRotation );

	U32 i = 0;
	for( i=0; i < uTrackCount; i++ )
	{
		// 5. TrackName
		IFXString trackName;
		pBitStreamX->ReadIFXStringX( trackName );
		IFXDECLARELOCAL(IFXNameMap, pNameMap);
		m_pCoreServices->GetNameMap(IID_IFXNameMap, (void**)&pNameMap);
		IFXCHECKX(pNameMap->Map(m_uLoadId, IFXSceneGraph::MOTION, trackName));
		// Find the track id from the track name
		U32 uTrackID = 0;
		IFXRESULT iFindResult = pMotionResource->FindTrack( &trackName, &uTrackID );
		if( IFXFAILURE( iFindResult ) ) {
			IFXCHECKX(pMotionResource->AddTrack( &trackName, &uTrackID ));
		}

		// 6. TimeCount
		U32 uTimeCount = 0;
		pBitStreamX->ReadU32X( uTimeCount );
		IFXKeyFrame *pKeyFrameArray = NULL;
		pKeyFrameArray = new IFXKeyFrame[uTimeCount];
		if( NULL == pKeyFrameArray ) {
			IFXCHECKX(IFX_E_OUT_OF_MEMORY);
		}

		// 7. InverseQuantDisplacement
		F32 fInverseQuantDisplacement = 1.0;
		pBitStreamX->ReadF32X(fInverseQuantDisplacement);

		// 8. InverseQuantScale
		F32 fInverseQuantScale = 1.0;
		pBitStreamX->ReadF32X(fInverseQuantScale);

		IFXKeyFrame thePredictedKeyFrame;
		U32 j = 0;
		for( j=0;  j < uTimeCount; j++ )
		{
			//  9. Time
			F32 fDiffTime = 0.0f;
			if(0==j || (uTimeCount-1) == j)
			{
				pBitStreamX->ReadF32X(fDiffTime);
			}
			else
			{
				U32 uDiffTime = 0;
				U8 u8SignTime = 0;
				pBitStreamX->ReadCompressedU8X(uACContextMotionSignTime,u8SignTime);
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffTime, uDiffTime );
				fDiffTime = (fInverseQuantTime*uDiffTime);
				if(u8SignTime & 1) {
					fDiffTime *= -1.0f;
				}
			}

			F32 fPredictedTime = thePredictedKeyFrame.Time();
			F32 fTime = fDiffTime + fPredictedTime;
			pKeyFrameArray[j].SetTime( fTime );

			//  10. Displacement
			F32 fdX=0.0f, fdY=0.0f, fdZ=0.0f;
			if(0==j || ((uTimeCount-1) == j && BlockType_ResourceMotionU3D == uBlockType ))
			{
				pBitStreamX->ReadF32X(fdX);
				pBitStreamX->ReadF32X(fdY);
				pBitStreamX->ReadF32X(fdZ);
			}
			else
			{
				U8 u8SignDisplacement = 0;
				U32 udX = 0;
				U32 udY = 0;
				U32 udZ = 0;
				pBitStreamX->ReadCompressedU8X(uACContextMotionSignDisplacement, u8SignDisplacement);
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffDisplacement, udX );
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffDisplacement, udY );
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffDisplacement, udZ );
				fdX = fInverseQuantDisplacement*udX;
				fdY = fInverseQuantDisplacement*udY;
				fdZ = fInverseQuantDisplacement*udZ;
				if(u8SignDisplacement & 1) {
					fdX *= -1.0;
				}
				if(u8SignDisplacement & 2) {
					fdY *= -1.0;
				}
				if(u8SignDisplacement & 4) {
					fdZ *= -1.0;
				}
			}

			IFXVector3 vDisplacement(0.0f,0.0f,0.0f);
			IFXVector3 vPredictedDisplacement = thePredictedKeyFrame.Location();
			IFXVector3 vDiffDisplacement(fdX,fdY,fdZ);
			vDisplacement.Add(vDiffDisplacement,vPredictedDisplacement);
			pKeyFrameArray[j].Location() = vDisplacement;

			//  11. Rotation
			U8 u8SignRot = 0;
			U32 uB=0,uC=0,uD=0;
			if(0==j || ((uTimeCount-1) == j && BlockType_ResourceMotionU3D == uBlockType ))
			{
				F32 fao,fbo,fco,fdo;
				pBitStreamX->ReadF32X(fao);
				pBitStreamX->ReadF32X(fbo);
				pBitStreamX->ReadF32X(fco);
				pBitStreamX->ReadF32X(fdo);
				IFXQuaternion vRotation(1.0f,0.0f,0.0f,0.0f);
				vRotation.Set(fao,fbo,fco,fdo);
				pKeyFrameArray[j].Rotation() = vRotation;
			} else {
				pBitStreamX->ReadCompressedU8X(uACContextMotionSignRotation,u8SignRot);
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffRotation, uB );
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffRotation, uC );
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffRotation, uD );
				F32 fb = fInverseQuantRotation*uB;
				F32 fc = fInverseQuantRotation*uC;
				F32 fd = fInverseQuantRotation*uD;
				if(fb > 1.0f) fb = 1.0f;
				if(fc > 1.0f) fc = 1.0f;
				if(fd > 1.0f) fd = 1.0f;
				F32 fa = (F32) sqrt(fabs(1.0 - ((F64)fb)*((F64)fb) - ((F64)fc)*((F64)fc) - ((F64)fd)*((F64)fd)));
				if(u8SignRot & 1) {
					fa *= -1.0;
				}
				if(u8SignRot & 2) {
					fb *= -1.0;
				}
				if(u8SignRot & 4) {
					fc *= -1.0;
				}
				if(u8SignRot & 8) {
					fd *= -1.0;
				}

				// Set the key frame values
				IFXQuaternion vDiffRotation( fa,fb,fc,fd );
				IFXQuaternion vPredictedRotation = thePredictedKeyFrame.Rotation();
				IFXQuaternion vRotationQ(1.0f,0.0f,0.0f,0.0f);
				vRotationQ.Multiply(vPredictedRotation,vDiffRotation);
				pKeyFrameArray[j].Rotation() = vRotationQ;
			}

			// 12. Scale
			F32 fdsX=0.0f, fdsY=0.0f, fdsZ=0.0f;
			if(0==j || ((uTimeCount-1) == j && BlockType_ResourceMotionU3D == uBlockType ))
			{
				pBitStreamX->ReadF32X(fdsX);
				pBitStreamX->ReadF32X(fdsY);
				pBitStreamX->ReadF32X(fdsZ);
			} else {
				U8 u8SignScale = 0;
				U32 udsX = 0;
				U32 udsY = 0;
				U32 udsZ = 0;
				pBitStreamX->ReadCompressedU8X(uACContextMotionSignScale, u8SignScale);
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffScale, udsX );
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffScale, udsY );
				pBitStreamX->ReadCompressedU32X(uACContextMotionDiffScale, udsZ );
				fdsX = fInverseQuantScale*udsX;
				fdsY = fInverseQuantScale*udsY;
				fdsZ = fInverseQuantScale*udsZ;
				if(u8SignScale & 1) {
					fdsX *= -1.0;
				}
				if(u8SignScale & 2) {
					fdsY *= -1.0;
				}
				if(u8SignScale & 4) {
					fdsZ *= -1.0;
				}
			}

			IFXVector3 vScaleQ(0.0f,0.0f,0.0f);
			IFXVector3 vPredictedScaleQ = thePredictedKeyFrame.Scale();
			IFXVector3 vDiffScaleQ(fdsX,fdsY,fdsZ);
			vScaleQ.Add(vDiffScaleQ,vPredictedScaleQ);
			pKeyFrameArray[j].Scale() = vScaleQ;

			// Set the predicted frame for the next key frame
			thePredictedKeyFrame = pKeyFrameArray[j];
		}

		// Set the key frame array to the motion resource
		IFXCHECKX(pMotionResource->ClearTrack( uTrackID ));
		IFXCHECKX(pMotionResource->InsertKeyFrames( uTrackID,uTimeCount,pKeyFrameArray ));
		IFXDELETE_ARRAY( pKeyFrameArray );
	}

	// Now, add a fully-mapped mixer to the mixer palette for this motion
	{
		U32 uMixerID = 0;
		IFXDECLARELOCAL(IFXPalette,pMixerPalette);
		IFXCHECKX(pSceneGraph->GetPalette( IFXSceneGraph::MIXER, &pMixerPalette ));
		IFXRESULT iFindResult = pMixerPalette->Find( &stringMotionName,&uMixerID );
		// if not found, add it to the palette
		if ( IFXFAILURE( iFindResult ) ) {
			IFXCHECKX(pMixerPalette->Add( &stringMotionName,&uMixerID ));
		}

		// now, try to get the motion resource pointer
		IFXDECLARELOCAL(IFXMixerConstruct, pMixerConstruct );
		IFXRESULT iGetResourceResult = pMixerPalette->GetResourcePtr(uMixerID,IID_IFXMixerConstruct,(void**)&pMixerConstruct);
		// if there was no resource pointer, then create one
		if (IFXFAILURE(iGetResourceResult)) {
			IFXCHECKX(IFXCreateComponent( CID_IFXMixerConstruct, IID_IFXMixerConstruct,( void** )&pMixerConstruct ));
			IFXASSERT(pMotionResource);
			pMixerConstruct->SetMotionResource(pMotionResource);

			// Set the scenegraph
			IFXCHECKX(pMixerConstruct->SetSceneGraph( pSceneGraph ));
			pMixerConstruct->SetExternalFlag(m_bExternal);
			pMixerConstruct->SetPriority(rDataBlockX.GetPriorityX(), FALSE, FALSE);

			// set the resource pointer in the palette
			IFXDECLARELOCAL(IFXUnknown,pUnknown);
			IFXCHECKX(pMixerConstruct->QueryInterface(IID_IFXUnknown, (void**)&pUnknown));
			IFXCHECKX(pMixerPalette->SetResourcePtr( uMixerID,pUnknown ));
		}
	}
}