Exemplo n.º 1
0
// --[ Method ]---------------------------------------------------------------
//
//  - Class     : CVector3
//  - Prototype : bool operator != (const CVector3& vector) const
//
//  - Purpose   : Comparison operator
//
// ---------------------------------------------------------------------------
bool CVector3::operator != (const CVector3& vector) const
{
	if(!ARE_EQUAL(vector.X(), m_fX)) return true;
	if(!ARE_EQUAL(vector.Y(), m_fY)) return true;
	if(!ARE_EQUAL(vector.Z(), m_fZ)) return true;

	return false;
}
Exemplo n.º 2
0
		void tCreateImage() {
			fsm->generate(5, 3, 2);
			string path = DATA_PATH;
			path += "tmp/";
			auto filename = fsm->writeDOTfile(path);
			ARE_EQUAL(true, !filename.empty(), "This %s cannot be saved into path '%s' in DOT format.",
				machineTypeNames[fsm->getType()], path.c_str());
			ARE_EQUAL(true, FSMmodel::createGIF(filename, true), "GIF was not created/shown for %s", filename.c_str());
			ARE_EQUAL(true, FSMmodel::createJPG(filename, true), "JPG was not created/shown for %s", filename.c_str());
			ARE_EQUAL(true, FSMmodel::createPNG(filename, true), "PNG was not created/shown for %s", filename.c_str());
		}
Exemplo n.º 3
0
		/// includes tests for getNumberOfStates/Inputs/Outputs()
		/// and confirms generate(), removeTransition(), removeState()
		void tGenerateSaveLoad() {
			DEBUG_MSG("Generate: %s", machineTypeNames[fsm->getType()]);
			fsm->generate(0, 0, 0);// = create(1,1,1) is minimum
			/// ERR: <type>::generate - the number of states needs to be greater than 0 (set to 1)
			/// ERR: <type>::generate - the number of inputs needs to be greater than 0 (set to 1)
			/// ERR: <type>::generate - the number of outputs needs to be greater than 0 (set to 1)
			ARE_EQUAL(fsm->getNumberOfStates(), state_t(1), "The number of states is not correct.");
			ARE_EQUAL(fsm->getNumberOfInputs(), input_t(1), "The number of inputs is not correct.");
			ARE_EQUAL(fsm->getNumberOfOutputs(), output_t(1), "The number of outputs is not correct.");
			tSaveLoad();

			fsm->generate(5, 3, 2);
			ARE_EQUAL(fsm->getNumberOfStates(), state_t(5), "The number of states is not correct.");
			ARE_EQUAL(fsm->getNumberOfInputs(), input_t(3), "The number of inputs is not correct.");
			ARE_EQUAL(fsm->getNumberOfOutputs(), output_t(2), "The number of outputs is not correct.");
			tSaveLoad();

			fsm->removeTransition(0, 0);
			fsm->removeTransition(1, 1);
			fsm->removeTransition(2, 2);
			/// 3 transitions * 2 machines = 6 ERRs if fsm->isOutputTransition()
			/// <type>::getOutput - there is no such transition
			fsm->removeState(3);
			/// if fsm->isOutputTransition() && there was a transition to state 3, then 2 ERRs:
			/// <type>::getOutput - there is no such transition
			tSaveLoad();
		}
Exemplo n.º 4
0
		/// includes tests for getNumberOfStates/Inputs/Outputs()
		/// and confirms create(), removeTransition()
		void tCreateSaveLoad() {
			DEBUG_MSG("Create: %s", machineTypeNames[fsm->getType()]);
			fsm->create(0, 0, 0);// = create(1,0,0) is minimum
			/// ERR: <type>::create - the number of states needs to be greater than 0 (set to 1)
			ARE_EQUAL(fsm->getNumberOfStates(), state_t(1), "The number of states is not correct.");
			ARE_EQUAL(fsm->getNumberOfInputs(), input_t(0), "The number of inputs is not correct.");
			ARE_EQUAL(fsm->getNumberOfOutputs(), output_t(0), "The number of outputs is not correct.");
			tSaveLoad();

			fsm->create(5, 3, 2);
			ARE_EQUAL(fsm->getNumberOfStates(), state_t(5), "The number of states is not correct.");
			ARE_EQUAL(fsm->getNumberOfInputs(), input_t(3), "The number of inputs is not correct.");
			ARE_EQUAL(fsm->getNumberOfOutputs(), output_t(2), "The number of outputs is not correct.");
			/// 5 states * 3 inputs * 2 machines = 30 ERRs if fsm->isOutputTransition()
			/// <type>::getOutput - there is no such transition
			tSaveLoad();

			fsm->setTransition(0, 0, 0);
			fsm->setTransition(0, 1, 1);
			fsm->setTransition(0, 2, 2);
			fsm->setTransition(1, 0, 3);
			fsm->setTransition(2, 1, 4);
			fsm->setTransition(3, 2, 0);
			fsm->setTransition(4, 0, 2);
			/// (5 states * 3 inputs - 7 transitions) * 2 machines = 16 ERRs if fsm->isOutputTransition()
			/// <type>::getOutput - there is no such transition
			tSaveLoad();
		}
bool CFXBillboardScene::DoFrame(CDemo* pDemo, float fEffectTime, float fDemoTime)
{
	assert(pDemo);

	// Scene

	if(!m_pResScene)
	{
		FXRuntimeError("Scene resource not available");
		return false;
	}

	CSceneView* pSceneView = const_cast<CSceneView*>(((CResourceScene*)m_pResScene)->GetSceneView());

	if(!pSceneView)
	{
		FXRuntimeError("NULL pSceneView");
		return false;
	}

	// Texture

	if(!m_pResTexture)
	{
		FXRuntimeError("Texture resource not found");
		return false;
	}

	UtilGL::Texturing::CTexture2D* pTexture = const_cast<UtilGL::Texturing::CTexture2D*>(((CResourceTexture2D*)m_pResTexture)->GetTexture2D());

	if(!pTexture)
	{
		FXRuntimeError("WARNING: Texture not available, effect will draw flat quad");
	}

	// Vars

	CVarFloat::CValueFloat   valueStartTime;
	CVarSpeed::CValueSpeed   valueSpeed;
	CVarCombo::CValueCombo   valueRenderMode;
	CVarString::CValueString valueCamera;
	CVarFloat::CValueFloat   valueLoopLength;
	CVarFloat::CValueFloat   valueLoopStart;

	CVarColor::CValueColor   valueColor;
	CVarFloat::CValueFloat   valueSize;
	CVarFloat::CValueFloat   valueAlpha;
	CVarFloat::CValueFloat   valueAngle;
	CVarCombo::CValueCombo   valueBlendMode;
	CVarCombo::CValueCombo   valueFiltering;

	EvaluateVar("Start Time",  fEffectTime, &valueStartTime);
	EvaluateVar("Speed",       fEffectTime, &valueSpeed);
	EvaluateVar("Render Mode", fEffectTime, &valueRenderMode);
	EvaluateVar("Camera",      fEffectTime, &valueCamera);
	EvaluateVar("Loop Length", fEffectTime, &valueLoopLength);
	EvaluateVar("Loop Start",  fEffectTime, &valueLoopStart);

	EvaluateVar("Color",       fEffectTime, &valueColor);
	EvaluateVar("Size",        fEffectTime, &valueSize);
	EvaluateVar("Alpha",       fEffectTime, &valueAlpha);
	EvaluateVar("Angle",       fEffectTime, &valueAngle);
	EvaluateVar("Blend Mode",  fEffectTime, &valueBlendMode);
	EvaluateVar("Filtering",   fEffectTime, &valueFiltering);

	float fAlpha = valueAlpha.GetValue();
	CVector4 v4Color = valueColor.GetValue();
	v4Color.SetW(fAlpha);

	if(valueCamera.GetString() != m_strCamera)
	{
		// Camera string changed at runtime
		m_strCamera = valueCamera.GetString();
	}

	float fTime = valueStartTime.GetValue() + valueSpeed.Integrate(0.0f, fEffectTime);

	if(IS_ZERO(valueLoopLength.GetValue()))
	{
		ComputeLoop(valueLoopStart.GetValue(), m_fAnimEnd, &fTime);
	}
	else if(valueLoopLength.GetValue() > 0.0f)
	{
		ComputeLoop(valueLoopStart.GetValue(), valueLoopLength.GetValue(), &fTime);
	}

	pSceneView->SetActiveCamera(m_strCamera);

	CRenderVisitor::EMode eRenderMode = CRenderVisitor::MODE_FULLDETAIL;

	     if(valueRenderMode.GetValue() == "Full")  eRenderMode = CRenderVisitor::MODE_FULLDETAIL;
	else if(valueRenderMode.GetValue() == "Solid") eRenderMode = CRenderVisitor::MODE_SOLID;
	else if(valueRenderMode.GetValue() == "Wire")  eRenderMode = CRenderVisitor::MODE_WIREFRAME;

	CMatrix  mtxAddLocal, mtxAddWorld;
	CVector3 v3AddCamPos, v3AddCamAngles;
	EvaluateAddTransformVars(this, fEffectTime, &mtxAddLocal, &mtxAddWorld, &v3AddCamPos, &v3AddCamAngles);

	pSceneView->Transform(pDemo, fTime, mtxAddLocal, mtxAddWorld, v3AddCamPos, v3AddCamAngles);

	// States

	UtilGL::States::SetColor(v4Color);

	// Change filter mode

	bool bTextureAlpha = false;
	GLint minFilter, magFilter;

	if(pTexture)
	{
		pTexture->SetActive();

		if(pTexture->HasAlpha())
		{
			bTextureAlpha = true;
		}

		glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &minFilter);
		glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &magFilter);

		if(valueFiltering.GetValue() == "Yes")
		{
			// If it's point filtering, change it to linear, otherwise leave it as it is

			if(minFilter == GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			if(magFilter == GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		}
		else
		{
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		}
	}

	// Blending

	int nSrcBlend = UtilGL::States::BLEND_SRCALPHA;
	int nDstBlend = UtilGL::States::BLEND_INVSRCALPHA;

	     if(valueBlendMode.GetValue() == "Add")  nDstBlend = UtilGL::States::BLEND_ONE;
	else if(valueBlendMode.GetValue() == "Mult") nDstBlend = UtilGL::States::BLEND_INVSRCALPHA;

	if(ARE_EQUAL(fAlpha, 1.0f) && valueBlendMode.GetValue() == "Mult" && !bTextureAlpha)
	{
		nSrcBlend = UtilGL::States::BLEND_ONE;
		nDstBlend = UtilGL::States::BLEND_ZERO;
	}

	if(!((nSrcBlend == UtilGL::States::BLEND_ONE  && nDstBlend == UtilGL::States::BLEND_ZERO) ||
		 (nSrcBlend == UtilGL::States::BLEND_ZERO && nDstBlend == UtilGL::States::BLEND_ONE)))
	{
		UtilGL::States::Set(UtilGL::States::BLENDING, UtilGL::States::ENABLED);
		UtilGL::States::Set(UtilGL::States::SRCBLEND, nSrcBlend);
		UtilGL::States::Set(UtilGL::States::DSTBLEND, nDstBlend);
	}
	else
	{
		UtilGL::States::Set(UtilGL::States::BLENDING, UtilGL::States::DISABLED);
	}

	UtilGL::States::Set(UtilGL::States::LIGHTING,     UtilGL::States::DISABLED);
	UtilGL::States::Set(UtilGL::States::ZBUFFERWRITE, UtilGL::States::DISABLED);
	UtilGL::States::Set(UtilGL::States::ALPHATEST,    UtilGL::States::ENABLED);
	glAlphaFunc(GL_GREATER, 0.0f);

	CEnumVisitor enumVisitor(CNodeVisitor::TRAVERSAL_DOWNWARDS);
	enumVisitor.Reset();

	if(pSceneView->GetRootNode())
	{
		CNode* pRootNode = (CNode*)pSceneView->GetRootNode();
		pRootNode->AcceptVisitor(&enumVisitor);
	}

	if(valueRenderMode.GetValue() == "Solid")
	{
		pTexture = NULL;
	}
	else if(valueRenderMode.GetValue() == "Wire")
	{
		pTexture = NULL;
		UtilGL::States::Set(UtilGL::States::POLYGONMODE, UtilGL::States::POLYGONMODE_LINE);
	}

	for(int i = 0; i < enumVisitor.GetNumObjects(); i++)
	{
		CObject* pObject = enumVisitor.GetObject(i);

		UtilGL::Transforming::SetMatrix(UtilGL::Transforming::MATRIX_WORLD, pObject->GetAbsoluteTM());

		UtilGL::Rendering::DrawBillboards(	pObject->GetNumVertices(),
											pTexture,
											pObject->GetVertices(),
											NULL,
											valueSize.GetValue(),
											valueAngle.GetValue());
	}

	if(pTexture)
	{
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
	}

	UtilGL::States::Set(UtilGL::States::BLENDING,     UtilGL::States::DISABLED);
	UtilGL::States::Set(UtilGL::States::ALPHATEST,    UtilGL::States::DISABLED);
	UtilGL::States::Set(UtilGL::States::POLYGONMODE,  UtilGL::States::POLYGONMODE_FILL);
	UtilGL::States::Set(UtilGL::States::ZBUFFERWRITE, UtilGL::States::ENABLED);

	return true;
}
Exemplo n.º 6
0
		/// includes tests for getNumberOfStates/Inputs/Outputs(), getType(),
		///		isReduced(), isOutputState/Transition(), getStates(), addState(), removeState()
		///		save(), load()
		/// confirms getOutput(), getNextState()
		void tSaveLoad() {
			string path = DATA_PATH;
			path += "tmp/";
			string filename = fsm->save(path);
			ARE_EQUAL(!filename.empty(), true, "This %s cannot be saved into path '%s'.",
				machineTypeNames[fsm->getType()], path.c_str());
			ARE_EQUAL(fsm2->load(filename), true, "File '%s' cannot be loaded.", filename.c_str());
			DEBUG_MSG(filename.c_str());
			
			ARE_EQUAL(fsm->getType(), fsm2->getType(), "Types of machines are not equal.");
			ARE_EQUAL(fsm->getNumberOfStates(), fsm2->getNumberOfStates(), "The numbers of states are not equal.");
			ARE_EQUAL(fsm->getNumberOfInputs(), fsm2->getNumberOfInputs(), "The numbers of inputs are not equal.");
			ARE_EQUAL(fsm->getNumberOfOutputs(), fsm2->getNumberOfOutputs(), "The numbers of outputs are not equal.");
			ARE_EQUAL(fsm->isReduced(), fsm2->isReduced(), "The indicators of minimal form are not equal.");
			ARE_EQUAL(fsm->isOutputState(), fsm2->isOutputState(), "The indicators of state outputs are not equal.");
			ARE_EQUAL(fsm->isOutputTransition(), fsm2->isOutputTransition(), "The indicators of transition outputs are not equal.");
			
			auto states = fsm->getStates();
			ARE_EQUAL(fsm->getNumberOfStates(), state_t(states.size()), "The numbers of states are not equal.");
			auto states2 = fsm2->getStates();
			ARE_EQUAL(states == states2, true, "The sets of states are not equal.");
			ARE_EQUAL((find(states.begin(), states.end(), 0) != states.end()), true, "The initial state is missing.");

			for (state_t& state : states) {
				if (fsm->isOutputState()) {
					ARE_EQUAL(fsm->getOutput(state, STOUT_INPUT), fsm2->getOutput(state, STOUT_INPUT), 
						"The outputs of state %d are different.", state);
				}
				for (input_t i = 0; i < fsm->getNumberOfInputs(); i++) {
					state_t nextState = fsm->getNextState(state, i);
					//DEBUG_MSG("%d", nextState);
					if (fsm->isOutputTransition()) {
						output_t output = fsm->getOutput(state, i);
						ARE_EQUAL(output, fsm2->getOutput(state, i),
							"The outputs on input %d from state %d are different.", i, state);
						if (nextState == NULL_STATE) {
							ARE_EQUAL(WRONG_OUTPUT, output,
								"There is no transition on input %d from state %d but output %d is set.",
								i, state, output);
						}
					}
					ARE_EQUAL(nextState, fsm2->getNextState(state, i),
						"The next states on input %d from state %d are different.", i, state);
					ARE_EQUAL(nextState != WRONG_STATE, true, 
						"The next state on input %d from state %d is wrong.", i, state);
					if (nextState != NULL_STATE) {
						ARE_EQUAL((find(states.begin(), states.end(), nextState) != states.end()),
							true, "The next state is wrong.");
					}
				}
			}
			auto newState = fsm->addState();
			//DEBUG_MSG("%d", newState);
			ARE_EQUAL(fsm->getNumberOfStates(), fsm2->getNumberOfStates() + 1, "The numbers of states are to be different by one.");
			ARE_EQUAL(newState, fsm2->addState(), "IDs of new states are not equal.");
			ARE_EQUAL(fsm->getNumberOfStates(), fsm2->getNumberOfStates(), "The numbers of states are not equal.");
			fsm->removeState(newState);
			ARE_EQUAL(fsm->getNumberOfStates(), fsm2->getNumberOfStates() - 1, "The numbers of states are to be different by one.");
		}
Exemplo n.º 7
0
bool CFXMosaic::DoFrame(CDemo* pDemo, float fEffectTime, float fDemoTime)
{
	assert(pDemo);

	if(!m_pResTexture)
	{
		FXRuntimeError("Texture resource not found");
		return false;
	}

	UtilGL::Texturing::CTexture2D* pTexture = const_cast<UtilGL::Texturing::CTexture2D*>(((CResourceTexture2D*)m_pResTexture)->GetTexture2D());

	if(!pTexture)
	{
		FXRuntimeError("WARNING: Texture not available");
		return false;
	}

	if(m_vecTiles.size() < 1)
	{
		FXRuntimeError("WARNING: No tiles available");
		return false;
	}

	CVarFloat::CValueFloat valuePosX;
	CVarFloat::CValueFloat valuePosY;
	CVarFloat::CValueFloat valueWidth;
	CVarFloat::CValueFloat valueHeight;
	CVarFloat::CValueFloat valueScale;
	CVarFloat::CValueFloat valueAlpha;
	CVarFloat::CValueFloat valueAngle;
	CVarCombo::CValueCombo valueBlendMode;
	CVarCombo::CValueCombo valueFiltering;
	CVarInt::CValueInt     valueTilesX;
	CVarInt::CValueInt     valueTilesY;
	CVarInt::CValueInt     valueTileSourceWidth;
	CVarInt::CValueInt     valueTileSourceHeight;
	CVarFloat::CValueFloat valueChangeFrequency;
	CVarFloat::CValueFloat valueChangeFreqVariation;

	EvaluateVar("X Position",            fEffectTime, &valuePosX);
	EvaluateVar("Y Position",            fEffectTime, &valuePosY);
	EvaluateVar("Width",                 fEffectTime, &valueWidth);
	EvaluateVar("Height",                fEffectTime, &valueHeight);
	EvaluateVar("Scale",                 fEffectTime, &valueScale);
	EvaluateVar("Alpha",                 fEffectTime, &valueAlpha);
	EvaluateVar("Angle",                 fEffectTime, &valueAngle);
	EvaluateVar("Blend Mode",            fEffectTime, &valueBlendMode);
	EvaluateVar("Filtering",             fEffectTime, &valueFiltering);
	EvaluateVar("Tiles X",               fEffectTime, &valueTilesX);
	EvaluateVar("Tiles Y",               fEffectTime, &valueTilesY);
	EvaluateVar("Tile Source Width",     fEffectTime, &valueTileSourceWidth);
	EvaluateVar("Tile Source Height",    fEffectTime, &valueTileSourceHeight);
	EvaluateVar("Change Frequency",      fEffectTime, &valueChangeFrequency);
	EvaluateVar("Change Freq Variation", fEffectTime, &valueChangeFreqVariation);

	// Change filter mode

	GLint minFilter, magFilter;
	GLfloat fMaxAnisotropy;

	UtilGL::States::Set(UtilGL::States::TEXTURE2D, UtilGL::States::ENABLED);
	pTexture->SetActive();

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &minFilter);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &magFilter);

	if(UtilGL::Extensions::GetAvailableExtensions()->EXT_texture_filter_anisotropic)
	{
		glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fMaxAnisotropy);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
	}

	if(valueFiltering.GetValue() == "Yes")
	{
		// If it's point filtering, change it to linear, otherwise leave it as it is

		if(minFilter == GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		if(magFilter == GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}
	else
	{
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	}

	CVarFloat* pVarAngle = reinterpret_cast<CVarFloat*>(GetVar("Angle"));
	assert(pVarAngle);

	float fAlpha = valueAlpha.GetValue() > 1.0f ? 1.0f : valueAlpha.GetValue();

	if(fAlpha < ALMOST_ZERO)
	{
		return true;
	}

	CVector4 v4Color(1.0f, 1.0f, 1.0f, fAlpha);
	UtilGL::States::SetColor(v4Color);

	float fAngle = valueAngle.GetValue();

	if(IS_ZERO(fAngle) && !pVarAngle->IsConstant())
	{
		// Avoid aspect ratio problem (see UtilGL::Rendering::DrawRect())
		fAngle = fAngle < 0.0f ? fAngle - (ALMOST_ZERO * 2.0f) : fAngle + (ALMOST_ZERO * 2.0f);
	}

	int nSrcBlend = UtilGL::States::BLEND_SRCALPHA;
	int nDstBlend = UtilGL::States::BLEND_INVSRCALPHA;

	     if(valueBlendMode.GetValue() == "Add")  nDstBlend = UtilGL::States::BLEND_ONE;
	else if(valueBlendMode.GetValue() == "Mult") nDstBlend = UtilGL::States::BLEND_INVSRCALPHA;
	else if(valueBlendMode.GetValue() == "Color Mult")
	{
		nSrcBlend = UtilGL::States::BLEND_DSTCOLOR;
		nDstBlend = UtilGL::States::BLEND_ZERO;
	}

	if(ARE_EQUAL(fAlpha, 1.0f) && valueBlendMode.GetValue() == "Mult" && !pTexture->HasAlpha())
	{
		nSrcBlend = UtilGL::States::BLEND_ONE;
		nDstBlend = UtilGL::States::BLEND_ZERO;
	}

	if(!((nSrcBlend == UtilGL::States::BLEND_ONE  && nDstBlend == UtilGL::States::BLEND_ZERO) ||
		 (nSrcBlend == UtilGL::States::BLEND_ZERO && nDstBlend == UtilGL::States::BLEND_ONE)))
	{
		UtilGL::States::Set(UtilGL::States::BLENDING, UtilGL::States::ENABLED);
		UtilGL::States::Set(UtilGL::States::SRCBLEND, nSrcBlend);
		UtilGL::States::Set(UtilGL::States::DSTBLEND, nDstBlend);
	}
	else
	{
		UtilGL::States::Set(UtilGL::States::BLENDING, UtilGL::States::DISABLED);
	}

	UtilGL::States::Set(UtilGL::States::LIGHTING,  UtilGL::States::DISABLED);
	UtilGL::States::Set(UtilGL::States::ZBUFFER,   UtilGL::States::DISABLED);

	UtilGL::Transforming::ClearMatrix(UtilGL::Transforming::MATRIX_WORLD);
	UtilGL::Transforming::ClearMatrix(UtilGL::Transforming::MATRIX_VIEW);

	UtilGL::Transforming::ClearMatrix(UtilGL::Transforming::MATRIX_PROJECTION);
	glMatrixMode(GL_PROJECTION);
	glOrtho(0, pTexture->GetWidth(), pTexture->GetHeight(), 0, 0.0f, 10.0f);


	// Update ***********


	int nImgTilesX = pTexture && valueTileSourceWidth.GetValue()  > 0 ? pTexture->GetWidth()  / valueTileSourceWidth.GetValue()  : 1;
	int nImgTilesY = pTexture && valueTileSourceHeight.GetValue() > 0 ? pTexture->GetHeight() / valueTileSourceHeight.GetValue() : 1;

	float fChangePeriod = IS_ZERO(valueChangeFrequency.GetValue()) ? FLOAT_MAX : 1.0f / valueChangeFrequency.GetValue();

	if(fChangePeriod < 0.0001f) fChangePeriod = 0.0001f;

	while(MYFABSF(m_fLastUpdate - fEffectTime) > fChangePeriod)
	{
		int nRandTile = rand() % m_vecTiles.size();

		m_vecTiles[nRandTile].nImgTileX = rand() % nImgTilesX;
		m_vecTiles[nRandTile].nImgTileY = rand() % nImgTilesY;

		if(fEffectTime < m_fLastUpdate)
		{
			m_fLastUpdate -= fChangePeriod;
		}
		else
		{
			m_fLastUpdate += fChangePeriod;
		}
	}


	// Render ***********


	VECTILES::iterator it;

	float fUTileWidth  = (float)valueTileSourceWidth.GetValue()  / (float)pTexture->GetWidth();
	float fVTileHeight = (float)valueTileSourceHeight.GetValue() / (float)pTexture->GetHeight();

	int nTilesX = valueTilesX.GetValue() < 1 ? 1 : valueTilesX.GetValue();
	int nTilesY = valueTilesY.GetValue() < 1 ? 1 : valueTilesY.GetValue();

	for(it = m_vecTiles.begin(); it < m_vecTiles.end(); ++it)
	{
		STile tile = *it;

		float fTileWidth  = pTexture->GetWidth()  / (float)nTilesX;
		float fTileHeight = pTexture->GetHeight() / (float)nTilesY;
		float fPosX       = ((valuePosX.GetValue() - 0.5f) * pTexture->GetWidth())  + (fTileWidth  * tile.nX);
		float fPosY       = ((valuePosY.GetValue() - 0.5f) * pTexture->GetHeight()) + (fTileHeight * tile.nY);
		float fScaleX     = valueWidth.GetValue()  * valueScale.GetValue();
		float fScaleY     = valueHeight.GetValue() * valueScale.GetValue();
		float fU          = tile.nImgTileX * fUTileWidth;
		float fV          = 1.0f - (tile.nImgTileY * fVTileHeight);
		float fU2         = fU + fUTileWidth;
		float fV2         = fV - fVTileHeight;

		CVector3 v3Center(pTexture->GetWidth() * 0.5f, pTexture->GetHeight() * 0.5f, -5.0f);

		CMatrix worldMtx;
		worldMtx.SetIdentity();

		worldMtx.Translate(fPosX, fPosY, 0.0f);
		worldMtx.Translate(-v3Center.X(), -v3Center.Y(), 0.0f);
		worldMtx.Scale    (fScaleX, fScaleY, 1.0f);
		worldMtx.RotateZ  (fAngle);
		worldMtx.Translate(+v3Center.X(), +v3Center.Y(), 0.0f);

		UtilGL::Transforming::SetMatrix(UtilGL::Transforming::MATRIX_WORLD, worldMtx);

		glBegin(GL_QUADS);

		glTexCoord2f(fU, fV);
		glVertex3f(0.0f, 0.0f, -5.0f);

		glTexCoord2f(fU, fV2);
		glVertex3f(0.0f, fTileHeight, -5.0f);

		glTexCoord2f(fU2, fV2);
		glVertex3f(fTileWidth, fTileHeight, -5.0f);

		glTexCoord2f(fU2, fV);
		glVertex3f(fTileWidth, 0.0f, -5.0f);

		glEnd();
	}

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0f, pDemo->GetAspect(), 1.0f, 1000.0f);

	// Restore filtering

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
	UtilGL::States::Set(UtilGL::States::TEXTURE2D, UtilGL::States::DISABLED);

	if(UtilGL::Extensions::GetAvailableExtensions()->EXT_texture_filter_anisotropic)
	{
		glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fMaxAnisotropy);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnisotropy);
	}

	UtilGL::States::Set(UtilGL::States::TEXTURE2D, UtilGL::States::DISABLED);
	UtilGL::States::Set(UtilGL::States::BLENDING,  UtilGL::States::DISABLED);
	UtilGL::States::Set(UtilGL::States::ZBUFFER,   UtilGL::States::ENABLED);

	return true;
}
Exemplo n.º 8
0
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CStravaganzaMaxTools
//
//  - prototype : bool BuildShaders()
//
//  - Purpose   : Builds the shader list from MAX's materials.
//                Preview mode requires texture files to be stored with full
//                path in order to load them. When we export, we only store the
//                filename. Another thing is that in the export mode, we copy
//                all textures into the path specified by the user if that
//                option is checked.
//
// -----------------------------------------------------------------------------
bool CStravaganzaMaxTools::BuildShaders()
{
	std::vector<Mtl*>::iterator it;

	assert(m_vecShaders.empty());

	if(!m_bPreview && m_bCopyTextures && m_strTexturePath == "")
	{
		CLogger::NotifyWindow("Textures won't be copied\nSpecify a valid output texture path first");
	}

	LOG.Write("\n\n-Building shaders: ");

	for(it = m_vecMaterials.begin(); it != m_vecMaterials.end(); ++it)
	{
		Mtl* pMaxMaterial = *it;
		assert(pMaxMaterial);

		LOG.Write("\n    %s", pMaxMaterial->GetName().data());
		CShaderStandard* pShaderStd = new CShaderStandard;
		pShaderStd->SetName(pMaxMaterial->GetName().data());

		// Properties

		StdMat2 *pMaxStandardMtl = NULL;
		StdMat2 *pMaxBakedMtl    = NULL;

		float fAlpha;

		if(pMaxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
		{
			pMaxStandardMtl = (StdMat2 *)pMaxMaterial;
		}
		else if(pMaxMaterial->ClassID() == Class_ID(BAKE_SHELL_CLASS_ID, 0))
		{
			pMaxStandardMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(0);
			pMaxBakedMtl    = (StdMat2 *)pMaxMaterial->GetSubMtl(1);
		}

		if(pMaxStandardMtl)
		{
			// Standard material

			fAlpha = pMaxStandardMtl->GetOpacity(0);

			Shader* pMaxShader = pMaxStandardMtl->GetShader();

			CVector4 v4Specular = ColorToVector4(pMaxStandardMtl->GetSpecular(0), 0.0f) * pMaxShader->GetSpecularLevel(0, 0);

			pShaderStd->SetAmbient  (ColorToVector4(pMaxStandardMtl->GetAmbient(0),  0.0f));
			pShaderStd->SetDiffuse  (ColorToVector4(pMaxStandardMtl->GetDiffuse(0),  fAlpha));
			pShaderStd->SetSpecular (v4Specular);
			pShaderStd->SetShininess(pMaxShader->GetGlossiness(0, 0) * 128.0f);

			if(pMaxStandardMtl->GetTwoSided() == TRUE)
			{
				pShaderStd->SetTwoSided(true);
			}

			// Need to cast to StdMat2 in order to get access to IsFaceted().
			// ¿Is StdMat2 always the interface for standard materials?
			if(((StdMat2*)pMaxStandardMtl)->IsFaceted())
			{
				pShaderStd->SetFaceted(true);
			}

			if(pMaxStandardMtl->GetWire() == TRUE)
			{
				pShaderStd->SetPostWire(true);
				pShaderStd->SetWireLineThickness(pMaxStandardMtl->GetWireSize(0));
			}
		}
		else
		{
			// Material != Standard

			fAlpha = 1.0f; // pMaxMaterial->GetXParency();

			pShaderStd->SetAmbient  (ColorToVector4(pMaxMaterial->GetAmbient(),  0.0f));
			pShaderStd->SetDiffuse  (ColorToVector4(pMaxMaterial->GetDiffuse(),  fAlpha));
			pShaderStd->SetSpecular (CVector4(0.0f, 0.0f, 0.0f, 0.0f));
			pShaderStd->SetShininess(0.0f);
		}

		// Layers

		if(!pMaxStandardMtl)
		{
			m_vecShaders.push_back(pShaderStd);
			continue;
		}

		bool bDiffuseMap32Bits = false;
		StdMat2 *pStandardMtl;

		for(int i = 0; i < 3; i++)
		{
			int nMap;

			pStandardMtl = pMaxStandardMtl;

			// 0 = diffuse, 1 == bump, 2 = lightmap (self illumination slot) or envmap (reflection slot)

			if(i == 0)
			{
				nMap = ID_DI;
			}
			else if(i == 1)
			{
				nMap = ID_BU;

				// If its a baked material, get the bump map from there

				if(pMaxBakedMtl)
				{
					pStandardMtl = pMaxBakedMtl;
				}
			}
			else if(i == 2)
			{
				bool bBaked = false;

				// If its a baked material, get the map2 (lightmap) from there

				if(pMaxBakedMtl)
				{
					if(pMaxBakedMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED)
					{
						bBaked       = true;
						nMap         = ID_SI;
						pStandardMtl = pMaxBakedMtl;
					}
				}

				if(!bBaked)
				{
					if(pStandardMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED)
					{
						nMap = ID_SI;
					}
					else
					{
						nMap = ID_RL;
					}
				}
			}

			// Check validity

			if(pStandardMtl->GetMapState(nMap) != MAXMAPSTATE_ENABLED)
			{
				if(i == 0)
				{
					LOG.Write("\n        No diffuse. Skipping.");
					break;
				}

				continue;
			}

			Texmap* pMaxTexmap = pStandardMtl->GetSubTexmap(nMap);

			if(!pMaxTexmap)
			{
				if(i == 0)
				{
					LOG.Write("\n        No diffuse. Skipping.");
					break;
				}

				continue;
			}

			// Get texmaps

			std::vector<std::string> vecTextures, vecPaths;

			CShaderStandard::SLayerInfo  layerInfo;
			CShaderStandard::SBitmapInfo bitmapInfo;

			if(pMaxTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))
			{
				BitmapTex* pMaxBitmapTex = (BitmapTex*)pMaxTexmap;
				Bitmap*    pMaxBitmap    = pMaxBitmapTex->GetBitmap(SECONDS_TO_TICKS(m_fStartTime));
				StdUVGen*  pMaxUVGen     = pMaxBitmapTex->GetUVGen();

				if(!pMaxBitmap)
				{
					if(i == 0)
					{
						LOG.Write("\n        Invalid diffuse. Skipping.");
						break;
					}
					continue;
				}

				assert(pMaxUVGen);

				BitmapInfo bi = pMaxBitmap->Storage()->bi;

				// bi.Name() returns the full path
				// bi.Filename() returns just the filename

				vecTextures.push_back(bi.Filename());
				vecPaths.   push_back(bi.Name());

				LOG.Write("\n        Bitmap %s", vecTextures[0].data());

				// Check if diffuse texture has alpha channel

				if(i == 0)
				{
					CBitmap    bitmap;
					CInputFile bitmapFile;

					if(!bitmapFile.Open(bi.Name(), false))
					{
						CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load file %s", bi.Name());
					}
					else
					{
						if(!bitmap.Load(&bitmapFile, GetFileExt(bi.Name())))
						{
							CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load bitmap %s", bi.Name());
						}
						else
						{
							if(bitmap.GetBpp() == 32)
							{
								bDiffuseMap32Bits = true;
								LOG.Write(" (with alpha channel)");
							}
							bitmap.Free();
						}
						bitmapFile.Close();
					}
				}

				// Ok, copy properties

				layerInfo.texInfo.bLoop        = false;
				layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURE2D;

				bitmapInfo.strFile         = m_bPreview ? bi.Name() : bi.Filename();
				bitmapInfo.bTile           = ((pMaxUVGen->GetTextureTiling() & (U_WRAP | V_WRAP)) == (U_WRAP | V_WRAP)) ? true : false;
				bitmapInfo.fSeconds        = 0.0f;
				bitmapInfo.bForceFiltering = false;
				bitmapInfo.eFilter         = UtilGL::Texturing::FILTER_TRILINEAR; // won't be used (forcefiltering = false)
				
				layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo);

				layerInfo.eTexEnv          = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE;
				layerInfo.eUVGen           = pMaxUVGen->GetCoordMapping(0) == UVMAP_SPHERE_ENV ? CShaderStandard::UVGEN_ENVMAPPING : CShaderStandard::UVGEN_EXPLICITMAPPING;
				layerInfo.uMapChannel      = pMaxUVGen->GetMapChannel();
				layerInfo.v3ScrollSpeed    = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3RotationSpeed  = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3ScrollOffset   = CVector3(pMaxUVGen->GetUOffs(0), pMaxUVGen->GetVOffs(0), 0.0f);
				layerInfo.v3RotationOffset = CVector3(pMaxUVGen->GetUAng(0),  pMaxUVGen->GetVAng(0),  pMaxUVGen->GetWAng(0));
			}
			else if(pMaxTexmap->ClassID() == Class_ID(ACUBIC_CLASS_ID, 0))
			{
				ACubic*       pMaxCubic  = (ACubic*)pMaxTexmap;
				IParamBlock2* pBlock     = pMaxCubic->pblock;
				Interval      validRange = m_pMaxInterface->GetAnimRange();

				for(int nFace = 0; nFace < 6; nFace++)
				{
					int nMaxFace;

					switch(nFace)
					{
					case 0: nMaxFace = 3; break;
					case 1: nMaxFace = 2; break;
					case 2: nMaxFace = 1; break;
					case 3: nMaxFace = 0; break;
					case 4: nMaxFace = 5; break;
					case 5: nMaxFace = 4; break;
					}

					TCHAR *name;
					pBlock->GetValue(acubic_bitmap_names, TICKS_TO_SECONDS(m_fStartTime), name, validRange, nMaxFace);

					vecPaths.push_back(name);

					CStr path, file, ext;
					SplitFilename(CStr(name), &path, &file, &ext);

					std::string strFile = std::string(file.data()) + ext.data();

					vecTextures.push_back(strFile);

					bitmapInfo.strFile         = m_bPreview ? name : strFile;
					bitmapInfo.bTile           = false;
					bitmapInfo.fSeconds        = 0.0f;
					bitmapInfo.bForceFiltering = false;
					bitmapInfo.eFilter         = UtilGL::Texturing::FILTER_TRILINEAR;
					
					layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo);
				}

				layerInfo.texInfo.bLoop        = false;
				layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURECUBEMAP;

				layerInfo.eTexEnv          = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE;
				layerInfo.eUVGen           = CShaderStandard::UVGEN_ENVMAPPING;
				layerInfo.uMapChannel      = 0;
				layerInfo.v3ScrollSpeed    = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3RotationSpeed  = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3ScrollOffset   = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3RotationOffset = CVector3(0.0f, 0.0f, 0.0f);
			}
			else
			{
				if(i == 0)
				{
					LOG.Write("\n        No diffuse. Skipping.");
					break;
				}
				continue;
			}

			if(!m_bPreview && m_bCopyTextures && m_strTexturePath != "")
			{
				for(int nTex = 0; nTex != vecTextures.size(); nTex++)
				{
					// Copy textures into the specified folder

					std::string strDestPath = m_strTexturePath;

					if(strDestPath[strDestPath.length() - 1] != '\\')
					{
						strDestPath.append("\\", 1);
					}

					strDestPath.append(vecTextures[nTex]);

					if(!CopyFile(vecPaths[nTex].data(), strDestPath.data(), FALSE))
					{
						CLogger::NotifyWindow("Unable to copy %s to\n%s", vecPaths[i], strDestPath.data());
					}
				}
			}

			if(layerInfo.eUVGen == CShaderStandard::UVGEN_ENVMAPPING && i == 1)
			{
				CLogger::NotifyWindow("%s : Bump with spheremapping not supported", pShaderStd->GetName().data());
			}
			else
			{
				// Add layer

				switch(i)
				{
				case 0: pShaderStd->SetLayer(CShaderStandard::LAYER_DIFF, layerInfo); break;
				case 1: pShaderStd->SetLayer(CShaderStandard::LAYER_BUMP, layerInfo); break;
				case 2: pShaderStd->SetLayer(CShaderStandard::LAYER_MAP2, layerInfo); break;
				}
			}
		}

		// ¿Do we need blending?

		if(ARE_EQUAL(fAlpha, 1.0f) && !bDiffuseMap32Bits)
		{
			pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_ONE);
			pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_ZERO);
		}
		else
		{
			pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_SRCALPHA);
			pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_INVSRCALPHA);
		}

		// Add shader

		m_vecShaders.push_back(pShaderStd);
	}

	return true;
}
Exemplo n.º 9
0
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CStravaganzaMaxTools
//
//  - prototype : int BuildPhysiqueData(INode* pMaxNode,
//										CObject* pObject,
//                                      std::vector<std::string>    &vecBoneNames,
//										std::vector<CBlendedVertex> &vecBlendedVertices)
//
//  - Purpose   : Builds the bone data for a given node. Returns the number
//                of bones processed (0 = failure).
//
// -----------------------------------------------------------------------------
int	CStravaganzaMaxTools::BuildPhysiqueData(INode* pMaxNode,
											CObject* pObject,
											std::vector<std::string>    &vecBoneNames,
											std::vector<CBlendedVertex> &vecBlendedVertices)

{
	int nCount       = 0;
	int nBoneCount   = 0;

	Modifier          *pPhyModifier  = NULL; // Physique modifier
	IPhysiqueExport   *pPhyExport    = NULL; // Physique export interface
	IPhyContextExport *pPhyObjExport = NULL; // Physique object export interface

	vecBoneNames.clear();
	vecBlendedVertices.clear();

	// Build bone list

	std::vector<INode*> vecMaxBones;

	if(!AddNodeBones(vecMaxBones, pMaxNode))
	{
		LOG.Write("\nWARNING - Error building node %s bone list", pMaxNode->GetName());
		return 0;
	}

	// Build bones name list

	for(nBoneCount = 0; nBoneCount < vecMaxBones.size(); nBoneCount++)
	{
		vecBoneNames.push_back(vecMaxBones[nBoneCount]->GetName());
	}

	// Get Physique modifier

	if(pPhyModifier = GetPhysiqueModifier(pMaxNode))
	{
		pPhyExport = (IPhysiqueExport *)pPhyModifier->GetInterface(I_PHYINTERFACE);

		if(pPhyExport == NULL)
		{
			LOG.Write("\nWARNING - Couldn't get Physique export interface.\nFailed with node %s.", pMaxNode->GetName());
			return 0;
		}
	}

	// Get physique object export interface

	pPhyObjExport = pPhyExport->GetContextInterface(pMaxNode);

	if(pPhyObjExport == NULL)
	{
		pPhyModifier->ReleaseInterface(I_PHYINTERFACE, pPhyExport);
		LOG.Write("\nWARNING - Unable to get physique context export.\nFailed with node %s.", pMaxNode->GetName());
		return 0;
	}

	// Convert to rigid for time independent vertex assignment
	// Allow blending to export multi-link assignments

	pPhyObjExport->ConvertToRigid(true);
	pPhyObjExport->AllowBlending(true);

	// Build deformable vertex list

	bool bOK = true;
	int  nBlendedCount = 0, nBlendedRigidCount = 0, nFloatingCount = 0;

	for(nCount = 0; nCount < pPhyObjExport->GetNumberVertices(); nCount++)
	{
		IPhyVertexExport       *pPhyVertExport;
		IPhyBlendedRigidVertex *pPhyBRVertexExport;
		IPhyRigidVertex        *pPhyRigidVertexExport;
		IPhyFloatingVertex	   *pPhyFloatingVertex;

		pPhyVertExport  = pPhyObjExport->GetVertexInterface(nCount);

		CBlendedVertex blendedVertex;
		float fTotalWeight   = 0.0f;
		bool  bFloatingBones = false;

		// Floating Vertex

		pPhyFloatingVertex = pPhyObjExport->GetFloatingVertexInterface(nCount);

		if(pPhyFloatingVertex)
		{
			bFloatingBones = true;

			CVector3 v3OffsetVector;
			float    fWeight;

			// More than one bone

			int nNumVtxBones = pPhyFloatingVertex->GetNumberNodes();

//			LOG.Write("\n%u - Floating, with %u bones", nCount, nNumVtxBones);

			for(nBoneCount = 0; nBoneCount < nNumVtxBones; nBoneCount++)
			{
				int nIndex = GetBoneIndex(vecMaxBones, pPhyFloatingVertex->GetNode(nBoneCount));

				if(nIndex == -1)
				{
					LOG.Write("\nWARNING - Unable to get bone index (%s)", pPhyFloatingVertex->GetNode(nBoneCount)->GetName());
					bOK = false;
					break;
				}

				float fTotal;

				v3OffsetVector = Point3ToVector3(pPhyFloatingVertex->GetOffsetVector(nBoneCount));
				fWeight        = pPhyFloatingVertex->GetWeight(nBoneCount, fTotal);
				fTotalWeight  += fWeight;//fTotal;
				//fWeight = fTotal;

//				LOG.Write("\n     Weight = %f (%s)", fWeight, pPhyFloatingVertex->GetNode(nBoneCount)->GetName());

				blendedVertex.AddLink(v3OffsetVector, nIndex, fWeight);
			}

//			LOG.Write("\n     Total = %f", fTotalWeight);

			if(!ARE_EQUAL(fTotalWeight, 1.0f))
			{
				LOG.Write("\n WARNING - Vertex %u has total weights %f", nCount, fTotalWeight);
			}

			nFloatingCount++;

			pPhyObjExport->ReleaseVertexInterface(pPhyFloatingVertex);
		}

		if(pPhyVertExport)
		{
			if(pPhyVertExport->GetVertexType() & BLENDED_TYPE)
			{
				CVector3 v3OffsetVector;
				float    fWeight;

				// More than one bone

				pPhyBRVertexExport = (IPhyBlendedRigidVertex *)pPhyVertExport;
				int nNumVtxBones   = pPhyBRVertexExport->GetNumberNodes();

//				LOG.Write("\n%u - Blended, with %u bones", nCount, nNumVtxBones);

				for(nBoneCount = 0; nBoneCount < nNumVtxBones; nBoneCount++)
				{
					int nIndex = GetBoneIndex(vecMaxBones, pPhyBRVertexExport->GetNode(nBoneCount));

					if(nIndex == -1)
					{
						LOG.Write("\nWARNING - Unable to get bone index (%s)", pPhyBRVertexExport->GetNode(nBoneCount)->GetName());
						bOK = false;
						break;
					}

					v3OffsetVector = Point3ToVector3(pPhyBRVertexExport->GetOffsetVector(nBoneCount));
					fWeight        = pPhyBRVertexExport->GetWeight(nBoneCount);
					fTotalWeight  += fWeight;

//					LOG.Write("\n     Weight = %f (%s)", fWeight, pPhyBRVertexExport->GetNode(nBoneCount)->GetName());

					blendedVertex.AddLink(v3OffsetVector, nIndex, fWeight);
				}

//				LOG.Write("\n     Total = %f", fTotalWeight);

				if(!ARE_EQUAL(fTotalWeight, 1.0f))
				{
					LOG.Write("\n WARNING - Vertex %u has total weights %f", nCount, fTotalWeight);
				}

				nBlendedCount++;
			}
			else
			{
				CVector3 v3OffsetVector;
				float    fWeight;

				// Single bone

				pPhyRigidVertexExport = (IPhyRigidVertex *)pPhyVertExport;

				int nIndex = GetBoneIndex(vecMaxBones, pPhyRigidVertexExport->GetNode());

				if(nIndex == -1)
				{
					LOG.Write("\nWARNING - Unable to get bone index (%s)", pPhyRigidVertexExport->GetNode()->GetName());
					bOK = false;
					break;
				}

				v3OffsetVector = Point3ToVector3(pPhyRigidVertexExport->GetOffsetVector());
				fWeight        = 1.0f;
				fTotalWeight   = 1.0f;

//				LOG.Write("\n%u - Rigid (%s)", nCount, pPhyRigidVertexExport->GetNode()->GetName());

				blendedVertex.AddLink(v3OffsetVector, nIndex, fWeight);

				nBlendedRigidCount++;
			}

			pPhyObjExport->ReleaseVertexInterface(pPhyVertExport);
		}

		for(int i = 0; i < blendedVertex.GetNumLinks(); i++)
		{
			// Normalize
			blendedVertex.SetWeight(i, blendedVertex.GetWeight(i) / fTotalWeight);
		}

		vecBlendedVertices.push_back(blendedVertex);
	}

	pPhyExport->ReleaseContextInterface(pPhyObjExport);
	pPhyModifier->ReleaseInterface(I_PHYINTERFACE, pPhyExport);

	if(!bOK)
	{
		vecMaxBones.clear();
		vecBoneNames.clear();
		vecBlendedVertices.clear();
	}
	else
	{
		LOG.Write("\nPhysique: %u bones, %u vertices (%u rigid, %u rigidblended, %u floating)",
				  vecBoneNames.size(),
				  vecBlendedVertices.size(),
				  nBlendedRigidCount,
				  nBlendedCount,
				  nFloatingCount);
	}

	return vecMaxBones.size();
}
Exemplo n.º 10
0
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CMatrix
//
//  - prototype : bool IsIdentity() const
//
//  - Purpose   : Returns true if matrix is the identity.
//                Use only if it avoids some computationally intense path.
//
// -----------------------------------------------------------------------------
bool CMatrix::IsIdentity() const
{
	return (ARE_EQUAL(m_fM[0][0], 1.0f) && ARE_EQUAL(m_fM[1][1], 1.0f) &&
			ARE_EQUAL(m_fM[2][2], 1.0f) && ARE_EQUAL(m_fM[3][3], 1.0f)) &&
		   (ARE_EQUAL(m_fM[0][1], 0.0f) && ARE_EQUAL(m_fM[0][2], 0.0f) &&
			ARE_EQUAL(m_fM[0][3], 0.0f) && ARE_EQUAL(m_fM[1][0], 0.0f) &&
			ARE_EQUAL(m_fM[1][2], 0.0f) && ARE_EQUAL(m_fM[1][3], 0.0f) &&
			ARE_EQUAL(m_fM[2][0], 0.0f) && ARE_EQUAL(m_fM[2][1], 0.0f) &&
			ARE_EQUAL(m_fM[2][3], 0.0f) && ARE_EQUAL(m_fM[3][0], 0.0f) &&
			ARE_EQUAL(m_fM[3][1], 0.0f) && ARE_EQUAL(m_fM[3][2], 0.0f));
}