HRESULT CVWScale3DTool::OnDoneScaling() { HRESULT hr = S_OK; POSITION pos; CTranslate3DObject * pCTrans = NULL; IVector *pvPos = NULL; for( pos = m_TransformList.GetHeadPosition(); pos != NULL; ) { pCTrans = m_TransformList.GetNext( pos ); if(NULL != pCTrans) { pvPos = NULL; if (FAILED(hr = pCTrans->m_pThing->get_ObjectProperty(bstrScale, (IObjectProperty**)&pvPos))) goto FAIL_EXIT; pvPos->set(pCTrans->currentLocation.x, pCTrans->currentLocation.y, pCTrans->currentLocation.z); } } FAIL_EXIT: SAFERELEASE(pvPos); return hr; }
STDMETHODIMP CVWExecuteGeomUndo::Redo( IVWUndoItem * predo ) { HRESULT hr = S_OK; VARIANT varTarget, varRedo; IThing *pThing = NULL; IVector *pvPos = NULL; IVector *pvUp = NULL; float fX, fY, fCenterX, fCenterY; static CComBSTR bstrScale("Scale"); static CComBSTR bstrPosition("Position"); static CComBSTR bstrDirection("Direction"); static CComBSTR bstrUp("Up"); IBoundary *pEC = NULL; IPropertyList *pBoundaryList = NULL; UndoData *pud; VARIANT_BOOL vbSafe; int i; VariantInit(&varTarget); VariantInit(&varRedo); hr = predo->get_UndoTarget(&varTarget); if (FAILED(hr)) goto FAIL_EXIT; hr = predo->get_UndoData(&varRedo); if (FAILED(hr)) goto FAIL_EXIT; pud = (UndoData*) varRedo.byref; ASSERT(pud); switch(pud->m_ot) { case SCALE: pThing = (IThing*) varTarget.pdispVal; ASSERT(pThing); if (FAILED(hr = pThing->get_ObjectProperty(bstrScale, (IObjectProperty**)&pvPos))) goto FAIL_EXIT; pvPos->set(pud->extra.scale.newScale.x, pud->extra.scale.newScale.y, pud->extra.scale.newScale.z); break; case SCALE2D: pEC = (IBoundary*) varTarget.pdispVal; ASSERT(pEC); fCenterX = pud->extra.scale.oldScale.x; fCenterY = pud->extra.scale.oldScale.y; i = 0; while (TRUE) { hr = pEC->GetVertexXYExt(i, &fX, &fY); if (hr == E_INVALIDARG) { hr = S_OK; break; } if(FAILED( hr )) goto FAIL_EXIT; hr = pEC->SetVertexXY(i, (fX - fCenterX) * pud->extra.scale.newScale.x + fCenterX, (fY - fCenterY) * pud->extra.scale.newScale.y + fCenterY); if(FAILED( hr )) goto FAIL_EXIT; i++; } break; case TRANSLATE: pThing = (IThing*) varTarget.pdispVal; ASSERT(pThing); if (FAILED(hr = pThing->get_ObjectProperty(bstrPosition, (IObjectProperty**)&pvPos))) goto FAIL_EXIT; pvPos->set(pud->extra.trans.newPosition.x, pud->extra.trans.newPosition.y, pud->extra.trans.newPosition.z); break; case TRANSLATE2D: pEC = (IBoundary*) varTarget.pdispVal; ASSERT(pEC); if (pud->extra.trans.nSelectedVert >= 0) { //hr = pEC->Translate(pud->extra.trans.newPosition.x + fX, pud->extra.trans.newPosition.y + fY); hr = pEC->Translate(pud->extra.trans.newPosition.x, pud->extra.trans.newPosition.y); if (FAILED(hr)) goto FAIL_EXIT; } else //Move the whole Boundary { hr = pEC->Translate(pud->extra.trans.newPosition.x, pud->extra.trans.newPosition.y); if (FAILED(hr)) goto FAIL_EXIT; } break; case ROTATE: pThing = (IThing*) varTarget.pdispVal; ASSERT(pThing); if (FAILED(hr = pThing->get_ObjectProperty(bstrDirection, (IObjectProperty**)&pvPos))) goto FAIL_EXIT; if (FAILED(hr = pThing->get_ObjectProperty(bstrUp, (IObjectProperty**)&pvUp))) goto FAIL_EXIT; pvPos->set(pud->extra.rotate.newDirection.x, pud->extra.rotate.newDirection.y, pud->extra.rotate.newDirection.z); pvUp->set(pud->extra.rotate.newUp.x, pud->extra.rotate.newUp.y, pud->extra.rotate.newUp.z); break; case ROTATE2D: pEC = (IBoundary*) varTarget.pdispVal; ASSERT(pEC); hr = pEC->Rotate(0.0f); break; case NEWBOUNDARY: pEC = (IBoundary*) varTarget.pdispVal; ASSERT(pEC); pud->extra.newboundary.BoundaryList->Add( CComVariant(pEC) ); if (FAILED(hr)) goto FAIL_EXIT; break; case DELETEBOUNDARY: pEC = (IBoundary*) varTarget.pdispVal; ASSERT(pEC); pud->extra.newboundary.BoundaryList->Remove(CComVariant(pEC)); if (FAILED(hr)) goto FAIL_EXIT; break; case DELETEVERTEX2D: pEC = (IBoundary*) varTarget.pdispVal; ASSERT(pEC); hr = pEC->DeleteVertexSafe(pud->extra.deletevertex.ecVert.index, &vbSafe); if (FAILED(hr)) goto FAIL_EXIT; hr = pud->extra.deletevertex.BoundaryList->Remove(CComVariant(pEC)); if (FAILED(hr)) goto FAIL_EXIT; hr = pud->extra.deletevertex.BoundaryList->Add(CComVariant(pEC)); if (FAILED(hr)) goto FAIL_EXIT; break; case INSERTVERTEX2D: pEC = (IBoundary*) varTarget.pdispVal; ASSERT(pEC); hr = pEC->InsertVertexSafe( pud->extra.insertvertex.ecVert.index, pud->extra.insertvertex.ecVert.x, pud->extra.insertvertex.ecVert.y, &vbSafe); if (FAILED(hr)) goto FAIL_EXIT; hr = pud->extra.insertvertex.BoundaryList->Remove(CComVariant(pEC)); if (FAILED(hr)) goto FAIL_EXIT; hr = pud->extra.insertvertex.BoundaryList->Add(CComVariant(pEC)); if (FAILED(hr)) goto FAIL_EXIT; break; case FLIPBOUNDARY: //pECB = (IBoundaryBuilder*) varTarget.pdispVal; //ASSERT(pECB); //pECB->ReverseVertices(); break; default: OutputDebugString("CVWExecuteGeomRedo::Redo: Unhandled redo type\n"); } FAIL_EXIT: SAFERELEASE(pvUp); SAFERELEASE(pvPos); SAFERELEASE(pEC); SAFERELEASE(pBoundaryList); return hr; }
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; }