Ejemplo n.º 1
0
void cUIMenu::FixMenuPos( eeVector2i& Pos, cUIMenu * Menu, cUIMenu * Parent, cUIMenuSubMenu * SubMenu ) {
	eeAABB qScreen( 0.f, 0.f, cUIManager::instance()->MainControl()->Size().Width(), cUIManager::instance()->MainControl()->Size().Height() );
	eeAABB qPos( Pos.x, Pos.y, Pos.x + Menu->Size().Width(), Pos.y + Menu->Size().Height() );

	if ( NULL != Parent && NULL != SubMenu ) {
		eeVector2i addToPos( 0, 0 );

		if ( NULL != SubMenu ) {
			addToPos.y = SubMenu->Size().Height();
		}

		eeVector2i sPos = SubMenu->Pos();
		SubMenu->ControlToScreen( sPos );

		eeVector2i pPos = Parent->Pos();
		Parent->ControlToScreen( pPos );

		eeAABB qParent( pPos.x, pPos.y, pPos.x + Parent->Size().Width(), pPos.y + Parent->Size().Height() );

		Pos.x		= qParent.Right;
		Pos.y		= sPos.y;
		qPos.Left	= Pos.x;
		qPos.Right	= qPos.Left + Menu->Size().Width();
		qPos.Top	= Pos.y;
		qPos.Bottom	= qPos.Top + Menu->Size().Height();

		if ( !qScreen.Contains( qPos ) ) {
			Pos.y		= sPos.y + SubMenu->Size().Height() - Menu->Size().Height();
			qPos.Top	= Pos.y;
			qPos.Bottom	= qPos.Top + Menu->Size().Height();

			if ( !qScreen.Contains( qPos ) ) {
				Pos.x 		= qParent.Left - Menu->Size().Width();
				Pos.y 		= sPos.y;
				qPos.Left	= Pos.x;
				qPos.Right	= qPos.Left + Menu->Size().Width();
				qPos.Top	= Pos.y;
				qPos.Bottom	= qPos.Top + Menu->Size().Height();

				if ( !qScreen.Contains( qPos ) ) {
					Pos.y		= sPos.y + SubMenu->Size().Height() - Menu->Size().Height();
					qPos.Top	= Pos.y;
					qPos.Bottom	= qPos.Top + Menu->Size().Height();
				}
			}
		}
	} else {
		if ( !qScreen.Contains( qPos ) ) {
			Pos.y		-= Menu->Size().Height();
			qPos.Top	-= Menu->Size().Height();
			qPos.Bottom	-= Menu->Size().Height();

			if ( !qScreen.Contains( qPos ) ) {
				Pos.x		-= Menu->Size().Width();
				qPos.Left	-= Menu->Size().Width();
				qPos.Right	-= Menu->Size().Width();

				if ( !qScreen.Contains( qPos ) ) {
					Pos.y		+= Menu->Size().Height();
					qPos.Top	+= Menu->Size().Height();
					qPos.Bottom	+= Menu->Size().Height();
				}
			}
		}
	}
}
Ejemplo n.º 2
0
void CModelGTF::RenderModel()
{
	// Go through all of the objects stored in this model
	for(int i = 0; i < m_Model.numOfObjects; i++)
	{
		// Get the current object that we are displaying
		t3DObject *pObject = &m_Model.pObject[i];
		
		// Check if there are materials assigned to this object and 
		// enable texture mapping if necessary, otherwise turn it off.
		if(pObject->numOfMaterials >= 1)
			glEnable(GL_TEXTURE_2D);
		else
			glDisable(GL_TEXTURE_2D);

		// Go through all of the faces (polygons) of the object and draw them
		for(int j = 0; j < pObject->numOfFaces; j++)
		{
			// Now let's see if there are any materials that need binding
			if(pObject->numOfMaterials >= 1)
			{
				// Create a static int to hold the last texture ID
				static int lastTexID = -1;

				// Extract the current textureID for this face from our face data
				int textureID = m_Model.pMaterials[pObject->pFaces[j].textureID].texureId;

				// If the current texture ID isn't the same as last time, bind the texture.
				if(textureID != lastTexID && textureID >= 0 && textureID < (int)strTextures.size())
					glBindTexture(GL_TEXTURE_2D, m_Textures[textureID]);

				// Store the current textureID in our static int for next time
				lastTexID = textureID;
			}

			// Start drawing our model triangles
			glBegin(GL_TRIANGLES);

				// Go through each vertex of the triangle and draw it.
				for(int whichVertex = 0; whichVertex < 3; whichVertex++)
				{
					// Make sure there are texture coordinates for this
					if(pObject->pTexVerts) 
					{
						// Here we grab the texture index from our face information
						int texIndex = pObject->pFaces[j].coordIndex[whichVertex];

						// Assign the texture coordinate to this vertex
						glTexCoord2f(pObject->pTexVerts[ texIndex ].x, 
									 pObject->pTexVerts[ texIndex ].y);
					}

					// Grab the current vertex index from our face information
					int vertIndex = pObject->pFaces[j].vertIndex[whichVertex];


//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

					// Now we get to the beef of the tutorial.  Below is where we
					// handle the calculations for our animation.  Basically what
					// happens is we grab the current and the next frame of animation
					// data.  With that data (the weights and transformations) we
					// do spherical interpolation (quaternion rotations) and linear
					// interpolation (the translations) to get a smooth transformation
					// between each frame of animation.  There isn't anything to
					// difficult about the concepts, but the math is the challenging
					// part.  The only math that is new to this tutorial is the
					// calculations of multiplying a quaternion by a 3D vector.

					// Extract the current vertex and draw it
					CVector3 vPos = pObject->pVerts[vertIndex];					

					// If there is no animation, just render the original
					// vertex and continue (skip the animation calculations).
					if(!pObject->bAnimated)
					{
						glVertex3f(vPos.x, vPos.y, vPos.z);
						continue;
					}

					// This will be our final vertex position to render
					CVector3 vNewPos(0, 0, 0);

					// Just to specify the index, we store our vertex index as a blendIndex.
					// This will index into our weight list.
					int blendIndex = vertIndex;

					// Now comes the crazy code :)  We now will go through every single
					// weight influence and add up all the influences and transformations
					// to our current vertex.
					for(int b=0; b < pObject->vWeightInfo[blendIndex].numBlendLinks; b++)
					{
						// Grab the current bone index from our weight list.  Remember that
						// the X variable stores the bone index and the Y stores the weight.
						int boneIndex = (int)pObject->vWeightInfo[blendIndex].pWeightInfo[b].x;

						// Make sure that the index we got isn't out of range of our bones
						if(boneIndex > pObject->numBones)
							return;

						// Now we want to grab the translation and rotation data for both the
						// current and the next frame of animation.  That way we can interpolate
						// between the two frames to make the animation look smoother.  So here
						// we grab pointers to the current and next matrix information for the
						// current bone we are working with.
						tBoneMatrix *pBoneMatrix1 = &(pObject->vBoneInfo[m_Model.currentFrame].pBoneMatrices[boneIndex]);
						tBoneMatrix *pBoneMatrix2 = &(pObject->vBoneInfo[m_Model.nextFrame].pBoneMatrices[boneIndex]);

						// First we want to perform the spherical-linear interpolation between
						// the two quaternions (rotations) for the current and next frame.
						CQuaternion	qPos(pBoneMatrix1->qRotation); 
						CQuaternion	qPos2(pBoneMatrix2->qRotation); 
						CQuaternion qNew = qPos.Slerp(qPos, qPos2, m_Model.t);

						// To apply the interpolated rotation we multiply our rotation by
						// the original position of the vertex.  This will then use our
						// function that we created at the top of this file which multiplies a
						// quaternion by a vector.  Once we do that, we store the new 3D vector.
						CVector3 vTempPos = qNew * vPos;

						// Next we grab the translations for the current and next frame
						CVector3 vPosition = pBoneMatrix1->vTranslation;
						CVector3 vNextPosition = pBoneMatrix2->vTranslation;
						
						// Using a simple linear-interpolation equation, we use our time "t"
						// value to interpolate between the current and next translation.  This
						// gives us a smooth transition between each frame of animation.
						vTempPos.x += vPosition.x + m_Model.t * (vNextPosition.x - vPosition.x);
						vTempPos.y += vPosition.y + m_Model.t * (vNextPosition.y - vPosition.y);
						vTempPos.z += vPosition.z + m_Model.t * (vNextPosition.z - vPosition.z);

						// If there is a special weight for this vertex we want to extract
						// that and apply it to our current vertex.  If the model isn't using
						// weighted animation then the weight will just be 1.0, which will do
						// nothing to the vertex when applied.  Remember that the Y value of
						// our weight-info list is the actual weight value to be applied.
						float weight = pObject->vWeightInfo[blendIndex].pWeightInfo[b].y;

						// Apply the weight value to our current vertex and add it to our
						// final transformed vertex position.
						vNewPos += vTempPos * weight;
					}

					// vNewPos has our final position that was transformed, so render it.
					glVertex3f(vNewPos.x, vNewPos.y, vNewPos.z);

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////


				}

			// Stop drawing polygons
			glEnd();
		}
	}
}