//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; }
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; }