//The function recursively builds up the transformation of the pThing 
//until it's in room-space coordinates
HRESULT C2DThingCoordTransformer::BuildTransformation(IThing * pThing, IThing * pParentThing)
{
	IVector * pVector = NULL;
	HRESULT hr = S_OK;
	IThing* pTmpParentThing = NULL;
	D3DRMMATRIX4D tmpMatrix;
	float flScaleX, flScaleY, flScaleZ;
	float flThingX, flThingY, flThingZ, // Position of current Thing having cells edited
	      flThingDirX, flThingDirY, flThingDirZ; // Orientation of current Thing having cells edited

	if (!pThing || !pParentThing)
		goto EXIT_FAIL;

	// Store the position Vector of the Thing
	hr = pThing->get_ObjectProperty(bstrPosition, (IObjectProperty **) &pVector);
	if( FAILED(hr) || !pVector) goto EXIT_FAIL;
	hr = pVector->get(&flThingX, &flThingY, &flThingZ);
	if( FAILED(hr) ) goto EXIT_FAIL;
	SAFERELEASE(pVector);

	// Get the Scale Vector of the Thing
	hr = pThing->get_ObjectProperty(bstrScale, (IObjectProperty **) &pVector);
	if( FAILED(hr) || !pVector) goto EXIT_FAIL;
	hr = pVector->get(&flScaleX, &flScaleY, &flScaleZ);
	if( FAILED(hr) ) goto EXIT_FAIL;
	SAFERELEASE(pVector);

	// Store the Direction Vector of the Thing
	hr = pThing->get_ObjectProperty(bstrDirection, (IObjectProperty **) &pVector);
	if( FAILED(hr) ) goto EXIT_FAIL;
	hr = pVector->get(&flThingDirX, &flThingDirY, &flThingDirZ);
	if( FAILED(hr) ) goto EXIT_FAIL;
	SAFERELEASE(pVector);

	IdentityMatrix(&tmpMatrix);
	ScaleMatrix(&tmpMatrix, flScaleX, flScaleY, flScaleZ);
	RotateMatrix(&tmpMatrix, flThingDirX, flThingDirY, flThingDirZ);
	TranslateMatrix(&tmpMatrix, flThingX, flThingY, flThingZ);
	PostMultiplyMatrix(&m_d3dMatrix, &tmpMatrix);

	IdentityMatrix(&tmpMatrix);
	TranslateMatrix(&tmpMatrix, -flThingX, -flThingY, -flThingZ);
	InverseRotateMatrix(&tmpMatrix, flThingDirX, flThingDirY, flThingDirZ);
	ScaleMatrix(&tmpMatrix, 1.0f / flScaleX, 1.0f / flScaleY, 1.0f / flScaleZ);
	PostMultiplyMatrix(&m_d3dInverseMatrix, &tmpMatrix);

	hr = pParentThing->get_Container(&pTmpParentThing);
	if ( SUCCEEDED(hr) && pTmpParentThing)
	{
		BuildTransformation(pParentThing, pTmpParentThing);
	}


EXIT_FAIL:
	SAFERELEASE(pTmpParentThing);
	SAFERELEASE(pVector);
	return hr;
}
示例#2
0
 void izracunajKoeficijente() {
     for(int i = 0; i < (int)faces.size(); ++i) {
         int i0 = faces[i].indexes[0];
         int i1 = faces[i].indexes[1];
         int i2 = faces[i].indexes[2];
         IVector *v1 = new Vector(new double[3]{vertices[i1].x - vertices[i0].x, vertices[i1].y - vertices[i0].y, vertices[i1].z - vertices[i0].z }, 3);
         IVector *v2 = new Vector(new double[3]{vertices[i2].x - vertices[i0].x, vertices[i2].y - vertices[i0].y, vertices[i2].z - vertices[i0].z }, 3);
         IVector *n = v1->nVectorProduct(v2);
         faces[i].a = n->get(0);
         faces[i].b = n->get(1);
         faces[i].c = n->get(2);
         faces[i].d = -faces[i].a * vertices[i1].x - faces[i].b * vertices[i1].y - faces[i].c * vertices[i1].z;
     }
 }
//Transform a vector from world to thing coords
HRESULT C2DThingCoordTransformer::TransformToThingCoordsNoTranslation(float * pflX, float * pflY, float * pflZ)
{
	HRESULT hr = S_OK;
	D3DVECTOR d3dVDst, d3dVSrc;
	IVector * pVector = NULL;


	if(NULL == pflX || NULL == pflY	|| NULL == pflZ)
	{
		hr = E_POINTER;
		goto EXIT_FAIL;
	}

	if (m_bDoTransform)
	{
		hr = m_pThing->get_ObjectProperty(bstrPosition, (IObjectProperty **) &pVector);
		if( FAILED(hr) ) goto EXIT_FAIL;

		hr = pVector->get(&d3dVSrc.x, &d3dVSrc.y, &d3dVSrc.z);
		if( FAILED(hr) ) goto EXIT_FAIL;

		d3dVSrc.x = *pflX + d3dVSrc.x;
		d3dVSrc.y = *pflY + d3dVSrc.y;
		d3dVSrc.z = *pflZ + d3dVSrc.z;

		InverseTransform(&d3dVDst, &d3dVSrc);

		*pflX = d3dVDst.x;
		*pflY = d3dVDst.y;
		*pflZ = d3dVDst.z;
	}

EXIT_FAIL:
	SAFERELEASE(pVector);

	return hr;
}
//This function builds a list of scalable objects from the selection list.
//pfValid is FALSE if there's nothing to scale.
STDMETHODIMP CVWScale3DTool::IsValid(IVWUIView *pVw,VARIANT_BOOL * pfValid)
{

	HRESULT hr = S_OK;
	CVWTransformPtr TransPtr;
	BSTR bstrReturnValue = NULL;
	VARIANT_BOOL	fLastItem = VARIANT_TRUE;
	COleVariant varProperty;
	IVWFrame *pVWFrame = NULL;
	IVWFrame *pVWParentFrame = NULL;
	CVWThingPtr ThingPtr;
	IVector			*pvPos = NULL;
	float			fPosx, fPosy, fPosz;
	CTranslate3DObject* pTmpTransObj;
	VARIANT_BOOL vbMoveable;

	ASSERT( pfValid );
	if (!pfValid ) return E_POINTER;

	*pfValid = VARIANT_FALSE;
	
	DestroyTransformList();

	if(	m_pSelectionList )
	{
		hr = m_pSelectionList->get_IsEmpty( &fLastItem  );
		if( FAILED(hr) )  goto EXIT_FAIL;

		if( VARIANT_FALSE == fLastItem ) 
		{
			hr = m_pSelectionList->FirstItem( &bstrReturnValue, &varProperty, &fLastItem );
			if( FAILED(hr) ) goto EXIT_FAIL;

			while( VARIANT_FALSE == fLastItem ) 
			{
				SAFEFREESTRING(bstrReturnValue);
				ThingPtr = varProperty;

				if (ThingPtr != NULL)
				{
					COleVariant			var; // get the geometry property
					CComBSTR			bstrType;

					SAFERELEASE(m_pWorld);
					hr = ThingPtr->get_World(&m_pWorld);
					if(FAILED(hr) || !m_pWorld) 	goto EXIT_FAIL;

					//Create our event vector if we don't have one already.
					if (!m_pVector)
					{
						hr = m_pWorld->CreateObjectPropertyExt(CLSID_Vector, NULL, (IObjectProperty**) &m_pVector);
						if (FAILED(hr)) goto EXIT_FAIL;
					}

					hr = ThingPtr->get_ObjectProperty(bstrScale, (IObjectProperty**)&pvPos);
					if (FAILED(hr)) goto EXIT_FAIL;

					hr = pvPos->get(&fPosx, &fPosy, &fPosz);
					if (FAILED(hr)) goto EXIT_FAIL;
					SAFERELEASE(pvPos);

					if (FAILED(hr = ThingPtr->CheckPropertySecurityExt(bstrScale, PS_WRITE)))
					{
						goto SECURITY_ERROR;
					}

					vbMoveable = VARIANT_TRUE;
					if (SUCCEEDED(hr = ThingPtr->get_BOOL(CComBSTR("IsMoveable"), &vbMoveable)) && !vbMoveable)
					{
						goto SECURITY_ERROR;
					}

					if (FAILED(hr = ThingPtr->get_Type(&bstrType.m_str)) || CompareElements(&bstrAvatar.m_str, &bstrType.m_str))
					{
						goto SECURITY_ERROR;
					}

					hr = ThingPtr->InvokeMethodExt(CComBSTR("GetFrame"), NULL, &var);
					if (FAILED(hr)) goto EXIT_FAIL;

					TransPtr = var;
					if( TransPtr != NULL )
					// At least one selected item has an IVWTransform
					{
						hr = TransPtr->QueryInterface(IID_IVWFrame, (void **) &pVWFrame);
						if (SUCCEEDED(hr) && pVWFrame != NULL)
						{
							hr = pVWFrame->GetParent(&pVWParentFrame);
							if (SUCCEEDED(hr) && pVWParentFrame != NULL)
							{
								*pfValid = VARIANT_TRUE;
								POSITION pos = m_TransformList.AddTail( pTmpTransObj = new CTranslate3DObject( ThingPtr, TransPtr, pVWFrame ) );

								pTmpTransObj->currentLocation.x = fPosx;
								pTmpTransObj->currentLocation.y = fPosy;
								pTmpTransObj->currentLocation.z = fPosz;
							}
		    				if( FAILED(hr) ) goto EXIT_FAIL;
							SAFERELEASE(pVWParentFrame);
						}
	    				if( FAILED(hr) ) goto EXIT_FAIL;
						SAFERELEASE(pVWFrame);
					}
SECURITY_ERROR:
					SAFERELEASE(pvPos);
					var.Clear();
				}
				varProperty.Clear();
				hr = m_pSelectionList->NextItem( &bstrReturnValue, &varProperty, &fLastItem );
    			if( FAILED(hr) ) goto EXIT_FAIL;
			}
		}  
	}
	goto EXIT_SUCCEED;
EXIT_FAIL:
	if (!m_TransformList.IsEmpty())
		DeletePtrListElements(&m_TransformList);

	*pfValid = FALSE;

EXIT_SUCCEED:
	SAFERELEASE(pvPos);
	SAFEFREESTRING(bstrReturnValue);
	SAFERELEASE(pVWFrame);
	SAFERELEASE(pVWParentFrame);

	return hr;

}