STDMETHODIMP CVectorObject::get_Rotation(float *pfTheta)
{
	D3DVECTOR rlvPreDef, rlvDir;
	D3DVALUE  valCosTheta;

	// The pre-defined angle.
	rlvPreDef.x = 0.0F;
	rlvPreDef.y	= 0.0F;
	rlvPreDef.z	= 1.0F;

	// Make a D3DVECTOR from this vector.
	rlvDir.x = m_x;
	rlvDir.y = m_y;
	rlvDir.z = m_z;

	D3DRMVectorNormalize(&rlvDir);

	// First need angle between the pre-defined angle and rlvDir.
	valCosTheta = D3DRMVectorDotProduct(&rlvPreDef, &rlvDir);
	*pfTheta = (D3DVALUE)acos(valCosTheta);

	// This will always be the acute angle. Since rotation will always be in positive direction we must
	// give correct angle (possibly obtuse) for that direction.
	if (rlvDir.x < 0.0F)
	{
		// Acute angle will not work, need obtuse angle.
		*pfTheta = (2*PI) - *pfTheta;
	}

	return S_OK;
}
Пример #2
0
/* Returns a random unit vector */
LPD3DVECTOR WINAPI D3DRMVectorRandom(LPD3DVECTOR d)
{
    d->u1.x = rand();
    d->u2.y = rand();
    d->u3.z = rand();
    D3DRMVectorNormalize(d);
    return d;
}
Пример #3
0
/* Rotation of a vector */
LPD3DVECTOR WINAPI D3DRMVectorRotate(LPD3DVECTOR r, LPD3DVECTOR v, LPD3DVECTOR axis, D3DVALUE theta)
{
    D3DRMQUATERNION quaternion1, quaternion2, quaternion3;
    D3DVECTOR norm;

    quaternion1.s = cos(theta * 0.5f);
    quaternion2.s = cos(theta * 0.5f);
    norm = *D3DRMVectorNormalize(axis);
    D3DRMVectorScale(&quaternion1.v, &norm, sin(theta * 0.5f));
    D3DRMVectorScale(&quaternion2.v, &norm, -sin(theta * 0.5f));
    quaternion3.s = 0.0;
    quaternion3.v = *v;
    D3DRMQuaternionMultiply(&quaternion1, &quaternion1, &quaternion3);
    D3DRMQuaternionMultiply(&quaternion1, &quaternion1, &quaternion2);

    *r = *D3DRMVectorNormalize(&quaternion1.v);
    return r;
}
HRESULT CVWScale3DTool::SetupEnvironment()
{
	HRESULT hr = S_OK;
	IThing* pGlobal = NULL;
	VARIANT_BOOL vbLock;
	D3DVECTOR tmpVec, upVec;

	hr = m_pWorld->get_Global(&pGlobal);
	if(FAILED(hr)) goto EXIT_FAIL;

	m_nAxisLock = 0;

	pGlobal->get_BOOL(bstrXAxisLocked, &vbLock);
	if(FAILED(hr)) goto EXIT_FAIL;
	if (vbLock)
		m_nAxisLock |= X_LOCK;

	pGlobal->get_BOOL(bstrYAxisLocked, &vbLock);
	if(FAILED(hr)) goto EXIT_FAIL;
	if (vbLock)
		m_nAxisLock |= Y_LOCK;

	pGlobal->get_BOOL(bstrZAxisLocked, &vbLock);
	if(FAILED(hr)) goto EXIT_FAIL;
	if (vbLock)
		m_nAxisLock |= Z_LOCK;

	pGlobal->get_BOOL(bstrGravity, &m_bGravity);
	if(FAILED(hr)) goto EXIT_FAIL;

	hr = m_pRMCameraFrame->GetOrientation(NULL, &tmpVec, &upVec);
	if(FAILED(hr)) goto EXIT_FAIL;

	D3DRMVectorNormalize(&upVec);

	//Figure out which editing mode we're in.
	if (upVec.y == 0.0f)
		m_nCameraMode = TOP;
	else
		m_nCameraMode = PERSPECTIVE;


EXIT_FAIL:
	SAFERELEASE(pGlobal);

	return hr;
}
Пример #5
0
// Calculate the normals for all the vertices of the patches of land.
void BoidsLand::gouraudShading( )
{
	// Local buffer for storing the current patches details.
	D3DRMVERTEX patchVertices[ 6 ];
	D3DVECTOR averageNormal;
	int faces;

	// Iterate through the patches of land on the landscape.
	for ( int row = 0; row < LAND_Z_SIZE; row++ )
	{
		for ( int col = 0; col < LAND_X_SIZE; col++ )
		{
			// Get the current state of the current vertex.
			landMesh -> GetVertices( patchGroups[ 0 ][ row ][ col ],
													0, 6, patchVertices );

			// Recalculate the normals from vertices 0 & 3.
			// Find the average of the face normals surrounding the vertex.
			averageNormal.x = 0;
			averageNormal.y = 0;
			averageNormal.z = 0;
			faces = 0;

			// Working round in a clockwise direction -
			// - starting from the current face.
			D3DRMVectorAdd( &averageNormal, &averageNormal,
									&patchFaceNormals[ row ][ col ][ 1 ] );
			D3DRMVectorAdd( &averageNormal, &averageNormal,
									&patchFaceNormals[ row ][ col ][ 0 ] );
			faces += 2;
			if ( row > 0 )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row - 1 ][ col ][ 0 ] );
				faces++;
			}
			if ( row > 0 && col > 0 )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row - 1 ][ col - 1 ][ 1 ] );
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row - 1 ][ col - 1 ][ 0 ] );
				faces += 2;
			}
			if ( col > 0 )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row ][ col - 1 ][ 1 ] );
				faces++;
			}

			averageNormal.x /= faces;
			averageNormal.y /= faces;
			averageNormal.z /= faces;
			// Normalise the resultant vector.
			D3DRMVectorNormalize( &averageNormal );
			// Update the normal of vertex 0.
			patchVertices[ 0 ].normal = averageNormal;
			// Update the normal of vertex 3.
			patchVertices[ 3 ].normal = averageNormal;


			// Recalculate the normal from vertex 1.
			// Find the average of the face normals surrounding the vertex.
			averageNormal.x = 0;
			averageNormal.y = 0;
			averageNormal.z = 0;
			faces = 0;


			// Working round in a clockwise direction -
			// - starting from the current face.
			D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row ][ col ][ 0 ] );
			faces++;
			if ( col > 0 )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row ][ col - 1 ][ 1 ] );
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row ][ col - 1 ][ 0 ] );
				faces += 2;
			}
			if ( col > 0 && ( ( row + 1 ) < LAND_Z_SIZE ) )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row + 1 ][ col - 1 ][ 1 ] );
				faces++;
			}
			if ( ( row + 1 ) < LAND_Z_SIZE )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row + 1 ][ col ][ 0 ] );
				D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row + 1 ][ col ][ 1 ] );
				faces += 2;
			}

			averageNormal.x /= faces;
			averageNormal.y /= faces;
			averageNormal.z /= faces;
			// Normalise the resultant vector.
			D3DRMVectorNormalize( &averageNormal );
			// Update the normal of vertex 1.
			patchVertices[ 1 ].normal = averageNormal;


			// Recalculate the normals from vertices 2 & 4.
			// Find the average of the face normals surrounding the vertex.
			averageNormal.x = 0;
			averageNormal.y = 0;
			averageNormal.z = 0;
			faces = 0;


			// Working round in a clockwise direction -
			// - starting from the current face.
			D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row ][ col ][ 1 ] );
			D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row ][ col ][ 0 ] );
			faces += 2;
			if ( ( row + 1 ) < LAND_Z_SIZE )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row + 1 ][ col ][ 1 ] );
				faces++;
			}
			if ( ( row + 1 ) < LAND_Z_SIZE && ( col + 1 ) < LAND_X_SIZE )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row + 1 ][ col + 1 ][ 0 ] );
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row + 1 ][ col + 1 ][ 1 ] );
				faces += 2;
			}
			if ( ( col + 1 ) < LAND_X_SIZE )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row ][ col + 1 ][ 0 ] );
				faces++;
			}

			averageNormal.x /= faces;
			averageNormal.y /= faces;
			averageNormal.z /= faces;
			// Normalise the resultant vector.
			D3DRMVectorNormalize( &averageNormal );
			// Update the normal of vertex 2.
			patchVertices[ 2 ].normal = averageNormal;
			// Update the normal of vertex 4.
			patchVertices[ 4 ].normal = averageNormal;


			// Recalculate the normal from vertex 5.
			// Find the average of the face normals surrounding the vertex.
			averageNormal.x = 0;
			averageNormal.y = 0;
			averageNormal.z = 0;
			faces = 0;


			// Working round in a clockwise direction -
			//- starting from the current face.
			D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row ][ col ][ 1 ] );
			faces++;
			if ( ( col + 1 ) < LAND_X_SIZE )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row ][ col + 1 ][ 0 ] );
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row ][ col + 1 ][ 1 ] );
				faces += 2;
			}
			if ( row > 0 && ( ( col + 1 ) < LAND_X_SIZE ) )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
							&patchFaceNormals[ row - 1 ][ col + 1 ][ 0 ] );
				faces++;
			}
			if ( row > 0 )
			{
				D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row - 1 ][ col ][ 1 ] );
				D3DRMVectorAdd( &averageNormal, &averageNormal,
								&patchFaceNormals[ row - 1 ][ col ][ 0 ] );
				faces += 2;
			}

			averageNormal.x /= faces;
			averageNormal.y /= faces;
			averageNormal.z /= faces;
			// Normalise the resultant vector.
			D3DRMVectorNormalize( &averageNormal );
			// Update the normal of vertex 5.
			patchVertices[ 5 ].normal = averageNormal;

			// Store the state of the current vertex.
			landMesh -> SetVertices( patchGroups[ 0 ][ row ][ col ],
													0, 6, patchVertices );
		}
	}
}
Пример #6
0
// Calculate the normals for all the face of the patches of land.
void BoidsLand::towerFlatShading( int side, D3DRMVERTEX towerVertices[ ] )
{
	// Calculate the normals for the triangular faces.
	// First make references to the values to simpify the code.
	D3DVALUE &x1 = towerVertices[ 0 ].position.x;
	D3DVALUE &x2 = towerVertices[ 1 ].position.x;
	D3DVALUE &x3 = towerVertices[ 2 ].position.x;
	D3DVALUE &y1 = towerVertices[ 0 ].position.y;
	D3DVALUE &y2 = towerVertices[ 1 ].position.y;
	D3DVALUE &y3 = towerVertices[ 2 ].position.y;
	D3DVALUE &z1 = towerVertices[ 0 ].position.z;
	D3DVALUE &z2 = towerVertices[ 1 ].position.z;
	D3DVALUE &z3 = towerVertices[ 2 ].position.z;

	D3DVALUE &x4 = towerVertices[ 3 ].position.x;
	D3DVALUE &x5 = towerVertices[ 4 ].position.x;
	D3DVALUE &x6 = towerVertices[ 5 ].position.x;
	D3DVALUE &y4 = towerVertices[ 3 ].position.y;
	D3DVALUE &y5 = towerVertices[ 4 ].position.y;
	D3DVALUE &y6 = towerVertices[ 5 ].position.y;
	D3DVALUE &z4 = towerVertices[ 3 ].position.z;
	D3DVALUE &z5 = towerVertices[ 4 ].position.z;
	D3DVALUE &z6 = towerVertices[ 5 ].position.z;

	// Produce two vectors from the first triangle.
	D3DVECTOR v1, v2, v3;
	v1.x = x3 - x2;
	v1.y = y3 - y2;
	v1.z = z3 - z2;

	v2.x = x1 - x3;
	v2.y = y1 - y3;
	v2.z = z1 - z3;

	// Find the cross product of the two vectors.
	D3DRMVectorCrossProduct( &v3, &v1, &v2 );
	// Normalise the resultant vector.
	D3DRMVectorNormalize( &v3 );

	// Set the normals of the first triangular face.
	towerFaceNormals[ side ][ 0 ] = v3;

	// Produce two vectors from the second triangle.
	v1.x = x6 - x5;
	v1.y = y6 - y5;
	v1.z = z6 - z5;

	v2.x = x4 - x6;
	v2.y = y4 - y6;
	v2.z = z4 - z6;

	// Find the cross product of the two vectors.
	D3DRMVectorCrossProduct( &v3, &v1, &v2 );
	// Normalise the resultant vector.
	D3DRMVectorNormalize( &v3 );

	// Set the normals of the second triangular face.
	towerFaceNormals[ side ][ 1 ] = v3;

	// Set the normals for the trianglar faces for flat shading.
	// First triangle.
	towerVertices[ 0 ].normal = towerFaceNormals[ side ][ 0 ];
	towerVertices[ 1 ].normal = towerFaceNormals[ side ][ 0 ];
	towerVertices[ 2 ].normal = towerFaceNormals[ side ][ 0 ];

	// Second triangle.
	towerVertices[ 3 ].normal = towerFaceNormals[ side ][ 1 ];
	towerVertices[ 4 ].normal = towerFaceNormals[ side ][ 1 ];
	towerVertices[ 5 ].normal = towerFaceNormals[ side ][ 1 ];
}
Пример #7
0
/* Return a unit quaternion that represents a rotation of an angle around an axis */
LPD3DRMQUATERNION WINAPI D3DRMQuaternionFromRotation(LPD3DRMQUATERNION q, LPD3DVECTOR v, D3DVALUE theta)
{
    q->s = cos(theta/2.0);
    D3DRMVectorScale(&q->v, D3DRMVectorNormalize(v), sin(theta/2.0));
    return q;
}
HRESULT CVWScale3DTool::ScaleSelectedObjects( float flDeltaX, float flDeltaY )
{
	CTranslate3DObject * pCTrans = NULL;
	IDirect3DRMFrame *pRMObjFrame = NULL;
	IDirect3DRMFrame *pRMParentFrame = NULL;
	IDirect3DRMFrame *pRMTmpFrame = NULL;
	D3DVECTOR axis;
	IVWFrame * pScene = NULL;
	BOOL bXAxisLocked, bYAxisLocked, bZAxisLocked;
	DWORD dwTimeNow;
	CComBSTR bstr1, bstr2, bstr3;
	CString tmpStr;
	static DWORD dwTime = - 1;
	HRESULT hr = S_OK;
	POSITION pos;
	CString szTmp;
	D3DVECTOR vecDelta, initialPos;
	IVector* vecPtr = NULL, *vecDestPtr = NULL;
	float fRot;
	float fX, fY, fZ, fTmp;

	D3DVECTOR vecCameraPos, vecObjToCam;

	if (IsPressed('S'))
	{
		flDeltaX *= SLOWKEY_SLOWFACTOR;
		flDeltaY *= SLOWKEY_SLOWFACTOR;
	}

	bXAxisLocked = m_nAxisLock & X_LOCK;
	bYAxisLocked = m_nAxisLock & Y_LOCK;
	bZAxisLocked = m_nAxisLock & Z_LOCK;

	if (m_nCameraMode == TOP)
	{
		flDeltaX /= 64.0f;
		flDeltaY /= 64.0f;
	}

	if (IsPressed('X'))
	{
		if (m_nCameraMode == TOP)
		{
			vecDelta.x = -flDeltaX / 4.0f; 
			vecDelta.y = 0.0f; 
			vecDelta.z = 0.0f;
		}
		else
		{
			vecDelta.x = -flDeltaX / 32.0f; 
			vecDelta.y = 0.0f; 
			vecDelta.z = 0.0f;
		}
	}
	else if (IsPressed('Y'))
	{
		if (m_nCameraMode == TOP)
		{
			vecDelta.x = 0.0; 
			vecDelta.y = 0.0f; 
			vecDelta.z = flDeltaY / 4.0f;
		}
		else
		{
			vecDelta.x = 0.0; 
			vecDelta.y = flDeltaY / 32.0f; 
			vecDelta.z = 0.0f;
		}
	}
	else if (IsPressed('Z'))
	{
		if (m_nCameraMode == TOP)
		{ 
			vecDelta.x = 0.0; 
			vecDelta.y = flDeltaY / 4.0f; 
			vecDelta.z = 0.0f;
		}
		else
		{
			vecDelta.x = 0.0; 
			vecDelta.y = 0.0f; 
			vecDelta.z = flDeltaY / 32.0f;
		}
	}
	else
	{
		if (m_nCameraMode == TOP)
		{
			vecDelta.x = (bXAxisLocked ? 0.0f : -flDeltaX / 4.0f);
			vecDelta.y = 0.0f; 
			vecDelta.z = (bZAxisLocked ? 0.0f : flDeltaY / 4.0f);
		}
		else
		{
			vecDelta.x = (bXAxisLocked ? 0.0f : flDeltaX / 32.0f); 
			vecDelta.y = 0.0f;
			vecDelta.z = (bZAxisLocked ? 0.0f : flDeltaY / 32.0f);  //0.0f; //(bZAxisLocked ? 0.0f : flDeltaX / 32.0f);
		}
	}
	
	hr = m_pRMCameraFrame->GetPosition(NULL, &vecCameraPos);
	if (FAILED(hr)) goto EXIT_FAIL;

	hr = CoCreateInstance(CLSID_Vector, NULL, CLSCTX_INPROC_SERVER, IID_IVector, (LPVOID*)&vecPtr);
	if (FAILED(hr)) goto EXIT_FAIL;

	hr = CoCreateInstance(CLSID_Vector, NULL, CLSCTX_INPROC_SERVER, IID_IVector, (LPVOID*)&vecDestPtr);
	if (FAILED(hr)) goto EXIT_FAIL;
	
	for( pos = m_TransformList.GetHeadPosition(); pos != NULL; )
	{
		pCTrans = m_TransformList.GetNext( pos );
		if(pCTrans != NULL && pCTrans->m_pTrans != NULL)
		{
			hr = pCTrans->m_pVWFrame->get_Frame3D(&pRMObjFrame);
			if (FAILED(hr) || (!pRMObjFrame)) goto EXIT_FAIL;

			hr = pRMObjFrame->GetParent(&pRMParentFrame);
			if (FAILED(hr) || (!pRMParentFrame)) goto EXIT_FAIL;

			pRMObjFrame->GetPosition(NULL, &initialPos);
			if (FAILED(hr)) goto EXIT_FAIL;

			if (!IsPressed(VK_SHIFT))
			{
				vecObjToCam.x = initialPos.x - vecCameraPos.x;
				vecObjToCam.y = 0.0f; //initialPos.y - vecCameraPos.y;
				vecObjToCam.z = initialPos.z - vecCameraPos.z;

				D3DRMVectorNormalize(&vecObjToCam);

				vecPtr->set(vecObjToCam.x, vecObjToCam.y, vecObjToCam.z);
				vecPtr->get_Rotation(&fRot);

				if (fRot >= 0.785 && fRot <= 2.355)
				{ //Camera is behind the object
				}
				else if (fRot >= 2.355 && fRot <= 3.925)
				{ //Camera is left of the object
					float fTmp;

					fTmp = vecDelta.x;
					vecDelta.x = vecDelta.z;
					vecDelta.z = fTmp;
				}
				else if (fRot >= 3.925 && fRot <= 5.495)
				{ //Camera is in front of the object
				}
				else
				{ //Camera is right of the object
					float fTmp;

					fTmp = vecDelta.x;
					vecDelta.x = vecDelta.z;
					vecDelta.z = fTmp;
				}

				ComputeEulerAngles(pCTrans->m_pVWFrame, vecDestPtr);
				vecDestPtr->get(&fX, &fY, &fZ);

				if (fX >= 0.785 && fX <= 2.355)
				{ //Camera is behind the object
					fTmp = vecDelta.z;
					vecDelta.z = vecDelta.y;
					vecDelta.y = fTmp;
				}
				else if (fX >= 2.355 && fX <= 3.925)
				{ //Camera is left of the object
				}
				else if (fX >= 3.925 && fX <= 5.495)
				{ //Camera is in front of the object
					fTmp = vecDelta.z;
					vecDelta.z = vecDelta.y;
					vecDelta.y = fTmp;
				}
				else
				{ //Camera is right of the object
				}

				if (fY >= 0.785 && fY <= 2.355) // && !(fX >= 2.355 && fX <= 3.925))
				{ //Camera is behind the object
					fTmp = vecDelta.x;
					vecDelta.x = vecDelta.z;
					vecDelta.z = fTmp;
				}
				else if (fY >= 2.355 && fY <= 3.925)
				{ //Camera is left of the object
				}
				else if (fY >= 3.925 && fY <= 5.495) // && !(fX >= 2.355 && fX <= 3.925) )
				{ //Camera is in front of the object
					fTmp = vecDelta.x;
					vecDelta.x = vecDelta.z;
					vecDelta.z = fTmp;
				}
				else
				{ //Camera is right of the object
				}
			}
			else
			{	//Shift it pressed
				vecDelta.y = vecDelta.x;
			}

			pRMObjFrame->SetPosition(NULL, 0.0f, 0.0f, 0.0f);
			if (FAILED(hr)) goto EXIT_FAIL;
		
			//Do a uniform (all axis) scaling
//				axis.x = 1.0f + (vecDelta.x > 0 ? vecDelta.x : vecDelta.z);
//				axis.y = 1.0f + (vecDelta.x > 0 ? vecDelta.x : vecDelta.z);
//				axis.z = 1.0f + (vecDelta.x > 0 ? vecDelta.x : vecDelta.z);
//			}
//			else //Normal perspective viewing
//			{
				axis.x = 1.0f + vecDelta.x;
				axis.y = 1.0f + vecDelta.y;
				axis.z = 1.0f + vecDelta.z;
//			}

			//Fix up current scale and fire UI event
			if (SIGN(pCTrans->currentLocation.x) == SIGN(axis.x) && axis.x != 0.0f)
			{
				fTmp = pCTrans->currentLocation.x;

				pCTrans->currentLocation.x *= axis.x;

				if (pCTrans->currentLocation.x < MIN_SCALE || pCTrans->currentLocation.x > MAX_SCALE)
				{
					pCTrans->currentLocation.x = fTmp;
					axis.x = 1.0f;
				}
			}
			else
				axis.x = 1.0f;

			if (SIGN(pCTrans->currentLocation.y) == SIGN(axis.y) && axis.y != 0.0f)
			{
				fTmp = pCTrans->currentLocation.y;

				pCTrans->currentLocation.y *= axis.y;

				if (pCTrans->currentLocation.y < MIN_SCALE || pCTrans->currentLocation.y > MAX_SCALE)
				{
					pCTrans->currentLocation.y = fTmp;
					axis.y = 1.0f;
				}
			}
			else
				axis.y = 1.0f;

			if (SIGN(pCTrans->currentLocation.z) == SIGN(axis.z) && axis.z != 0.0f)
			{
				fTmp = pCTrans->currentLocation.z;

				pCTrans->currentLocation.z *= axis.z;

				if (pCTrans->currentLocation.z < MIN_SCALE || pCTrans->currentLocation.z > MAX_SCALE)
				{
					pCTrans->currentLocation.z = fTmp;
					axis.z = 1.0f;
				}
			}
			else
				axis.z = 1.0f;

			hr = pRMObjFrame->AddScale(D3DRMCOMBINE_BEFORE, axis.x, axis.y, axis.z);
			if (FAILED(hr)) goto EXIT_FAIL;

			pRMObjFrame->SetPosition(NULL, initialPos.x, initialPos.y, initialPos.z);
			if (FAILED(hr)) goto EXIT_FAIL;

			dwTimeNow = GetTickCount();

			if (dwTimeNow - dwTime > 200)
			{
				tmpStr.Format("%0.3f", pCTrans->currentLocation.x);
				bstr1 = tmpStr;
				tmpStr.Format("%0.3f", pCTrans->currentLocation.y); 
				bstr2 = tmpStr;
				tmpStr.Format("%0.3f", pCTrans->currentLocation.z); 
				bstr3 = tmpStr;

				hr = InvokeToolEvent(TOOLEVENT_3DOBJECTSCALED, pCTrans->m_pThing, bstr1.m_str, bstr2.m_str, bstr3.m_str, VARIANT_TRUE);
				if(FAILED( hr )) goto EXIT_FAIL;

				dwTime = dwTimeNow;
			}

			SAFERELEASE(pRMObjFrame);
			SAFERELEASE(pRMParentFrame);
		}
	}

EXIT_FAIL:
	SAFERELEASE(pRMParentFrame);
	SAFERELEASE(pRMObjFrame);
	SAFERELEASE(pScene);
	SAFERELEASE(vecDestPtr);
	SAFERELEASE(vecPtr);
	
	return hr;
}