示例#1
0
	bool BMaxObject::UpdateModel(SceneState * sceneState /*= NULL*/)
	{
		if (!m_pAnimatedMesh)
			return false;
		int nIndex = (sceneState && IsLODEnabled()) ? m_pAnimatedMesh->GetLodIndex(sceneState->GetCameraToCurObjectDistance()/*, GetScaling()*/) : 0;
		CParaXModel* pModel = m_pAnimatedMesh->GetModel(nIndex);
		
		if (pModel == NULL)
			return false;
		// just a single standing animation is supported now and looped. 
		if (!m_CurrentAnim.IsValid())
			m_CurrentAnim = pModel->GetAnimIndexByID(0);
		if (m_CurrentAnim.IsValid() && IsAnimEnabled())
		{
			int nAnimLength = std::max(1, m_CurrentAnim.nEndFrame - m_CurrentAnim.nStartFrame);
			int nToDoFrame = (m_CurrentAnim.nCurrentFrame + (int)(sceneState->dTimeDelta * 1000)) % nAnimLength;
			m_CurrentAnim.nCurrentFrame = nToDoFrame;
		}
		pModel->m_CurrentAnim = m_CurrentAnim;
		pModel->m_NextAnim.nIndex = 0;
		pModel->m_BlendingAnim.MakeInvalid();
		pModel->blendingFactor = 0;
		pModel->animate(sceneState, NULL, GetAnimInstanceFields());
		return true;
	}
示例#2
0
	Matrix4* BMaxObject::GetAttachmentMatrix(Matrix4& matOut, int nAttachmentID /*= 0*/, int nRenderNumber /*= 0*/)
	{
		if (m_pAnimatedMesh && m_pAnimatedMesh->IsLoaded())
		{
			CParaXModel* pModel = m_pAnimatedMesh->GetModel();
			if (pModel)
			{
				Matrix4* pOut = &matOut;
				if (pModel->GetAttachmentMatrix(pOut, nAttachmentID, m_CurrentAnim, AnimIndex(), 0.f))
				{
					Matrix4 matScale;
					float fScaling = GetScaling();
					if (fabs(fScaling - 1.0f) > FLT_TOLERANCE)
					{
						ParaMatrixScaling(&matScale, fScaling, fScaling, fScaling);
						(*pOut) = (*pOut)*matScale;
					}
					return pOut;
				}
			}
		}
		return NULL;
	}
示例#3
0
bool CBoneAnimProvider::LoadAsset()
{
	if(m_bLoaded)
		return true;
	ParaXEntity* pAsset = m_asset.get();
	if(pAsset && pAsset->GetPrimaryTechniqueHandle() > 0)
	{
		CParaXModel* pModel = pAsset->GetModel();
		if(pModel)
		{
			m_asset.reset();
			m_bLoaded = true;

			// copy bone look up table
			memcpy(m_boneLookup, pModel->m_boneLookup, sizeof(m_boneLookup));

			// copy bones
			int nBones = pModel->GetObjectNum().nBones;
			m_bones.resize(nBones);
			for (int i=0;i<nBones;++i)
			{
				m_bones[i] = pModel->bones[i];
			}

			// copy animation sequence info
			int nAnimations = pModel->GetObjectNum().nAnimations;
			m_anims.resize(nAnimations);
			for (int i=0;i<nAnimations ;++i)
			{
				m_anims[i] = pModel->anims[i];
			}
			return true;
		}
	}

	return m_bLoaded;
}
示例#4
0
	void BMaxObject::LoadPhysics()
	{
		if (m_dwPhysicsMethod > 0 && IsPhysicsEnabled() && (GetStaticActorCount() == 0))
		{
			if (m_pAnimatedMesh && m_pAnimatedMesh->IsLoaded())
			{
				CParaXModel* ppMesh = m_pAnimatedMesh->GetModel();
				if (ppMesh == 0 || ppMesh->GetHeader().maxExtent.x <= 0.f)
				{
					EnablePhysics(false); // disable physics forever, if failed loading physics data
					return;
				}
				// get world transform matrix
				Matrix4 mxWorld;
				GetWorldTransform(mxWorld);
				IParaPhysicsActor* pActor = CGlobals::GetPhysicsWorld()->CreateStaticMesh(m_pAnimatedMesh.get(), mxWorld, m_nPhysicsGroup, &m_staticActors, this);
				if (m_staticActors.empty())
				{
					// disable physics forever, if no physics actors are loaded. 
					EnablePhysics(false);
				}
			}
		}
	}
示例#5
0
	HRESULT BMaxObject::Draw(SceneState * sceneState)
	{
		if (!m_pAnimatedMesh)
			return E_FAIL;
		if (GetPrimaryTechniqueHandle() < 0)
		{
			// try loading the asset if it has not been done before. 
			m_pAnimatedMesh->LoadAsset();
			if (m_pAnimatedMesh->IsLoaded())
			{
				SetPrimaryTechniqueHandle(m_pAnimatedMesh->GetPrimaryTechniqueHandle());
				UpdateGeometry();
			}
			return E_FAIL;
		}

		if (!CGlobals::GetEffectManager()->IsCurrentEffectValid())
		{
			return E_FAIL;
		}
		sceneState->SetCurrentSceneObject(this);

		int nIndex = (sceneState && sceneState->IsLODEnabled()) ?
			m_pAnimatedMesh->GetLodIndex(sceneState->GetCameraToCurObjectDistance()/*, GetScaling()*/) : 0;
		CParaXModel* pModel = m_pAnimatedMesh->GetModel(nIndex);
		if (pModel == NULL)
			return E_FAIL;
		
		int nRestoreSpecialTextures = -1;
		for (auto const & tex : mReplaceTextures)
		{
			if(pModel->specialTextures[tex.first] >= 0)
				pModel->replaceTextures[pModel->specialTextures[tex.first]] = tex.second;
			else
			{
				// if there is only one texture, we will force replace it even there is no special replaceable id redefined.
				if (pModel->GetObjectNum().nTextures <= 1 && nRestoreSpecialTextures<0)
				{
					nRestoreSpecialTextures = tex.first;
					pModel->specialTextures[tex.first] = tex.first;
					pModel->replaceTextures[pModel->specialTextures[tex.first]] = tex.second;
					break;
				}
			}
		}

		sceneState->SetCurrentSceneObject(this);
		SetFrameNumber(sceneState->m_nRenderCount);
		// get world transform matrix
		Matrix4 mxWorld;
		GetRenderMatrix(mxWorld);


		RenderDevicePtr pd3dDevice = sceneState->m_pd3dDevice;
		EffectManager* pEffectManager = CGlobals::GetEffectManager();
		pEffectManager->applyObjectLocalLighting(this);

		CEffectFile* pEffectFile = pEffectManager->GetCurrentEffectFile();
		CGlobals::GetWorldMatrixStack().push(mxWorld);

		ApplyBlockLighting(sceneState);

		
		CApplyObjectLevelParamBlock p(GetEffectParamBlock());

		if (pEffectFile == 0)
		{
			// TODO: Fixed Function. 
		}
		else
		{
			bool bUsePointTextureFilter = false;

			// apply block space lighting for object whose size is comparable to a single block size
			if (CheckAttribute(MESH_USE_LIGHT) && !(sceneState->IsShadowPass()))
			{
				BlockWorldClient* pBlockWorldClient = BlockWorldClient::GetInstance();
				if (pBlockWorldClient && pBlockWorldClient->IsInBlockWorld())
				{
					Vector3 vPos = GetPosition();
					vPos.y += 0.1f;
					Uint16x3 blockId_ws(0, 0, 0);
					BlockCommon::ConvertToBlockIndex(vPos.x, vPos.y, vPos.z, blockId_ws.x, blockId_ws.y, blockId_ws.z);
					DWORD dwPositionHash = blockId_ws.GetHashCode();
					uint8_t brightness[2];
					pBlockWorldClient->GetBlockMeshBrightness(blockId_ws, brightness, 2);
					// block light
					float fBlockLightness = Math::Max(pBlockWorldClient->GetLightBrightnessLinearFloat(brightness[0]), 0.1f);
					sceneState->GetCurrentLightStrength().y = fBlockLightness;
					// sun light
					float fSunLightness = Math::Max(pBlockWorldClient->GetLightBrightnessLinearFloat(brightness[1]), 0.1f);
					sceneState->GetCurrentLightStrength().x = fSunLightness;

					float fLightness = Math::Max(fBlockLightness, fSunLightness*pBlockWorldClient->GetSunIntensity());
					if (m_fLastBlockLight != fLightness)
					{
						float fMaxStep = (float)(sceneState->dTimeDelta*0.5f);
						if (dwPositionHash == m_dwLastBlockHash || m_dwLastBlockHash == 0)
							m_fLastBlockLight = fLightness;
						else
							Math::SmoothMoveFloat1(m_fLastBlockLight, fLightness, fMaxStep);

						fLightness = m_fLastBlockLight;
					}
					else
					{
						m_dwLastBlockHash = dwPositionHash;
					}
					sceneState->GetLocalMaterial().Ambient = (LinearColor(fLightness*0.7f, fLightness*0.7f, fLightness*0.7f, 1.f));
					sceneState->GetLocalMaterial().Diffuse = (LinearColor(fLightness*0.4f, fLightness*0.4f, fLightness*0.4f, 1.f));

					sceneState->EnableLocalMaterial(true);
					bUsePointTextureFilter = bUsePointTextureFilter || pBlockWorldClient->GetUsePointTextureFiltering();
				}
			}

			if (bUsePointTextureFilter)
			{
				pEffectManager->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
				pEffectManager->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
			}
			else
			{
				pEffectManager->SetSamplerState(0, D3DSAMP_MINFILTER, pEffectManager->GetDefaultSamplerState(0, D3DSAMP_MINFILTER));
				pEffectManager->SetSamplerState(0, D3DSAMP_MAGFILTER, pEffectManager->GetDefaultSamplerState(0, D3DSAMP_MAGFILTER));
			}

			// just a single standing animation is supported now and looped. 
			UpdateModel(sceneState);
			pModel->draw(sceneState, p.GetParamsBlock()); 
		}

		if (nRestoreSpecialTextures >= 0)
		{
			pModel->specialTextures[nRestoreSpecialTextures] = -1;
			pModel->replaceTextures[nRestoreSpecialTextures] = nullptr;
		}

		CGlobals::GetWorldMatrixStack().pop();
		return S_OK;
	}
示例#6
0
HRESULT ParaEngine::CLightObject::RenderMesh(SceneState * sceneState)
{
	if (!m_pAnimatedMesh)
		return E_FAIL;
	if (GetPrimaryTechniqueHandle() < 0)
	{
		// try loading the asset if it has not been done before. 
		m_pAnimatedMesh->LoadAsset();
		if (m_pAnimatedMesh->IsLoaded())
		{
			SetPrimaryTechniqueHandle(m_pAnimatedMesh->GetPrimaryTechniqueHandle());
			UpdateGeometry();
		}
		return E_FAIL;
	}

	if (!CGlobals::GetEffectManager()->IsCurrentEffectValid())
	{
		return E_FAIL;
	}

	CParaXModel* pModel = m_pAnimatedMesh->GetModel(0);
	if (pModel == NULL)
		return E_FAIL;

	sceneState->SetCurrentSceneObject(this);
	SetFrameNumber(sceneState->m_nRenderCount);
	// get world transform matrix
	Matrix4 mxWorld;
	GetRenderMatrix(mxWorld);

	RenderDevicePtr pd3dDevice = sceneState->m_pd3dDevice;
	EffectManager* pEffectManager = CGlobals::GetEffectManager();
	pEffectManager->applyObjectLocalLighting(this);

	CEffectFile* pEffectFile = pEffectManager->GetCurrentEffectFile();
	CGlobals::GetWorldMatrixStack().push(mxWorld);

	if (pEffectFile == 0)
	{
		// TODO: Fixed Function. 
	}
	else
	{
		// apply block space lighting for object whose size is comparable to a single block size
		BlockWorldClient* pBlockWorldClient = BlockWorldClient::GetInstance();
		if (pBlockWorldClient && pBlockWorldClient->IsInBlockWorld())
		{
			uint8_t brightness[2];
			Uint16x3 blockId_ws(0, 0, 0);
			Vector3 vPos = GetPosition();
			BlockCommon::ConvertToBlockIndex(vPos.x, vPos.y + 0.1f, vPos.z, blockId_ws.x, blockId_ws.y, blockId_ws.z);
			float fLightness;

			pBlockWorldClient->GetBlockMeshBrightness(blockId_ws, brightness);
			// block light
			float fBlockLightness = Math::Max(pBlockWorldClient->GetLightBrightnessFloat(brightness[0]), 0.1f);
			sceneState->GetCurrentLightStrength().y = fBlockLightness;
			// sun light
			fLightness = Math::Max(pBlockWorldClient->GetLightBrightnessFloat(brightness[1]), 0.1f);
			sceneState->GetCurrentLightStrength().x = fLightness;
			fLightness *= pBlockWorldClient->GetSunIntensity();
			fLightness = Math::Max(fLightness, fBlockLightness);
			
			sceneState->GetLocalMaterial().Ambient = (LinearColor(fLightness*0.7f, fLightness*0.7f, fLightness*0.7f, 1.f));
			sceneState->GetLocalMaterial().Diffuse = (LinearColor(fLightness*0.4f, fLightness*0.4f, fLightness*0.4f, 1.f));
			
			sceneState->EnableLocalMaterial(true);
		}

		// just a single standing animation is supported now and looped. 
		if (!m_CurrentAnim.IsValid())
			m_CurrentAnim = pModel->GetAnimIndexByID(0);
		if (m_CurrentAnim.IsValid())
		{
			int nAnimLength = std::max(1, m_CurrentAnim.nEndFrame - m_CurrentAnim.nStartFrame);
			int nToDoFrame = (m_CurrentAnim.nCurrentFrame + (int)(sceneState->dTimeDelta * 1000)) % nAnimLength;
			m_CurrentAnim.nCurrentFrame = nToDoFrame;
		}
		pModel->m_CurrentAnim = m_CurrentAnim;
		pModel->m_NextAnim.nIndex = 0;
		pModel->m_BlendingAnim.MakeInvalid();
		pModel->blendingFactor = 0;
		pModel->animate(sceneState, NULL);
		// force CParaXModel::BMAX_MODEL? 
		pModel->draw(sceneState, NULL);
	}

	CGlobals::GetWorldMatrixStack().pop();
	return S_OK;
}