Point Terrain::movingRevision(const Point& last, const Point& updated) { CC_UNUSED_PARAM(last); if (isInStandGround(updated)) { return ccp(0.0f, 0.0f); } BorderNode* pSgmt = borderEntry; Point wallVect, nextWallVect, sgmtStart, sgmtEnd, nextEnd, dividerVect; Point revised; do { sgmtStart = ccp(tileSize * pSgmt->segment.start.col, tileSize * pSgmt->segment.start.row); sgmtEnd = ccp(tileSize * pSgmt->segment.end.col, tileSize * pSgmt->segment.end.row); nextEnd = ccp(tileSize * pSgmt->next->segment.end.col, tileSize * pSgmt->next->segment.end.row); wallVect = ccpRotateByAngle(sgmtEnd - sgmtStart, ccp(0, 0), CC_DEGREES_TO_RADIANS(-90)); nextWallVect = ccpRotateByAngle(nextEnd - sgmtEnd, ccp(0, 0), CC_DEGREES_TO_RADIANS(-90)); if (ccpCross(sgmtEnd - sgmtStart, nextEnd - sgmtEnd) > 0) // 凸角 { if (pointOnLineSide(updated, sgmtStart, sgmtEnd) == POS_ON_THE_RIGHT && pointOnLineSide(updated, sgmtStart, sgmtStart + wallVect) == POS_ON_THE_LEFT && pointOnLineSide(updated, sgmtEnd, sgmtEnd + wallVect) == POS_ON_THE_RIGHT) { // 作个垂线修正.. revised = sgmtStart + ccpProject(updated - sgmtStart, sgmtEnd - sgmtStart); break; } else if (pointOnLineSide(updated, sgmtEnd, sgmtEnd + wallVect) == POS_ON_THE_LEFT && pointOnLineSide(updated, sgmtEnd, sgmtEnd + nextWallVect) == POS_ON_THE_RIGHT) { // 修正到当前边末端的凸角点.. revised = sgmtEnd; break; } } else // 凹角 { dividerVect = ccpNormalize(nextEnd - sgmtEnd) - ccpNormalize(sgmtEnd - sgmtStart); if (pointOnLineSide(updated, sgmtStart, sgmtEnd) == POS_ON_THE_RIGHT && pointOnLineSide(updated, sgmtStart, sgmtStart + wallVect) == POS_ON_THE_LEFT && pointOnLineSide(updated, sgmtEnd, sgmtEnd + dividerVect) == POS_ON_THE_RIGHT) { // 作个垂线修正.. revised = sgmtStart + ccpProject(updated - sgmtStart, sgmtEnd - sgmtStart); break; } } pSgmt = pSgmt->next; } while (pSgmt != borderEntry); return (revised - updated); }
// This is the main component method for interpereters and plugins. // May als be used in case of invokeable addons STDMETHODIMP RawComponent::InvokeEx( IMgaProject *project, IMgaFCO *currentobj, IMgaFCOs *selectedobjs, long param) { // Calling the user's initialization function if(CUdmApp::Initialize()) { return S_FALSE; } CComPtr<IMgaProject>ccpProject(project); long prefmask; ccpProject->get_Preferences(&prefmask); // KMS magic number MGAPREF_NO_NESTED_TX #define MGAPREF_NO_NESTED_TX 0x80 prefmask |= MGAPREF_NO_NESTED_TX; ccpProject->put_Preferences(prefmask); std::shared_ptr<CComPtr<IMgaProject>> mgaPrefRestore(std::addressof(ccpProject), [prefmask](ATL::CComPtr<IMgaProject>* p){ (*p)->put_Preferences(prefmask & (~MGAPREF_NO_NESTED_TX)); } ); CComPtr<IMgaComponentEx> constrMgr; CComPtr<IMgaComponentEx> cyphyAddon; // Finding constraint manager among the addons CComPtr<IMgaComponents> comps; COMTHROW( ccpProject->get_AddOnComponents(&comps)); MGACOLL_ITERATE(IMgaComponent, comps) { CComBSTR name; COMTHROW(MGACOLL_ITER->get_ComponentName(&name)); if(name == L"ConstraintManager") { constrMgr = CComQIPtr<IMgaComponentEx>(MGACOLL_ITER); } else if(name == L"CyPhyAddOn") { cyphyAddon = CComQIPtr<IMgaComponentEx>(MGACOLL_ITER); } } MGACOLL_ITERATE_END;