static LPDIRECT3DDEVICE9 GetDevice() { GraphicsWindow *GW; ViewExp *View; LPDIRECT3DDEVICE9 Device; View = GetCOREInterface()->GetActiveViewport(); if(View) { GW = View->getGW(); if(GW) { ID3D9GraphicsWindow *D3DGW = (ID3D9GraphicsWindow *)GW->GetInterface(D3D9_GRAPHICS_WINDOW_INTERFACE_ID); if(D3DGW) { Device = D3DGW->GetDevice(); return(Device); } } } return NULL; }
void U2MaxCameraExport::ExtractFromViewport(Interface* pIf) { ViewExp* viewport = pIf->GetActiveViewport(); if(viewport) { Matrix3 modelView, invModelView; viewport->GetAffineTM(modelView); invModelView = Inverse(modelView); Point3 up = invModelView.GetRow(0); // up Point3 right = invModelView.GetRow(1); // right Point3 look = invModelView.GetRow(2); Point3 eye = invModelView.GetRow(3); float fFov = viewport->GetFOV(); BOOL bIsPerp = viewport->IsPerspView(); pIf->ReleaseViewport(viewport); if(bIsPerp) { ; } else { ; } } }
void CrossSectionMouseProc::DrawCrossing(HWND hWnd) { if (mShapeData == NULL) return; BezierShape *shape = mShapeData->TempData(es)->GetShape(ip->GetTime()); if (shape == NULL) return; int polys = mSelectedSplines.Count(); if (polys <= 0) return; Spline3D *spline = shape->GetSpline(mSelectedSplines[polys-1]); int knots = spline->KnotCount(); Point3 p(0.0f, 0.0f, 0.0f); IPoint3 sp; ViewExp *vpt = ip->GetViewport(hWnd); GraphicsWindow *gw = vpt->getGW(); ip->ReleaseViewport(vpt); gw->setTransform(mObjToWorldTM); HDC hdc = GetDC(hWnd); SetROP2(hdc, R2_XORPEN); SetBkMode(hdc, TRANSPARENT); SelectObject(hdc,CreatePen(PS_DOT, 0, ComputeViewportXORDrawColor())); for (int i = 0, j = 0; i < 2 && i <= j; i++, j += (knots-1)) { if (knots > i) p = spline->GetKnotPoint(j); gw->wTransPoint(&p, &sp); MoveToEx(hdc,sp.x,sp.y,NULL); LineTo(hdc,mMouse.x,mMouse.y); } DeleteObject(SelectObject(hdc,GetStockObject(BLACK_PEN))); ReleaseDC(hWnd, hdc); }
void U2MaxCameraExport::Export(Interface* pIf, INode *pMaxNode, Object *obj) { CameraObject* camObj = (CameraObject*)obj; // get camera state Interval interval; CameraState camState; camObj->EvalCameraState(m_animStart, interval, &camState); bool bFixedCam = false; if(camObj->GetManualClip()) bFixedCam = true; float fFov = camState.fov; BOOL bIsOrtho = camState.isOrtho; float fInvAspectRatio = 1.0f / pIf->GetRendImageAspect(); if(bIsOrtho) { float fWidth = 640.0f / 4.0f; float fHeight = 480.0f / 4.0f; float fScalar = camObj->GetTDist(0) / 200.0f; } else { // add } if(bFixedCam) { float fNearPlane = camState.hither; float farPlane = camState.yon; } else { float nearPlane = 1.0f; float farPlane = 6000.0f; } ViewExp* viewport = pIf->GetActiveViewport(); if(viewport) { INode* pMaxViewCam = viewport->GetViewCamera(); if(pMaxNode == pMaxViewCam) { ; } pIf->ReleaseViewport(viewport); } else { ; } }
void ProtHelpObject::GetMat(TimeValue t, INode* inode, ViewExp& vpt, Matrix3& tm) { if ( ! vpt.IsAlive() ) { tm.Zero(); return; } tm = inode->GetObjectTM(t); tm.NoScale(); float scaleFactor = vpt.NonScalingObjectSize() * vpt.GetVPWorldWidth(tm.GetTrans()) / 360.0f; tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor)); }
int SegRefineMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; switch ( msg ) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: if(HitTest(vpt,&m,HITTYPE_POINT,0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); HitRecord *bestRec = rec; DWORD best = rec->distance; while(rec) { rec = rec->Next(); if(rec) { if(rec->distance < best) { best = rec->distance; bestRec = rec; } } } ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData); es->DoSegRefine(vpt, hit->shape, hit->poly, hit->index, m); } res = FALSE; break; case MOUSE_FREEMOVE: vpt->SnapPreview(m,m,NULL, SNAP_IN_3D); if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) { SetCursor(GetTransformCursor()); } else { SetCursor(LoadCursor(NULL,IDC_ARROW)); } break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
int TrimMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; // IntersectPt fromPt, toPt; BOOL extend = FALSE; switch ( msg ) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: if(HitTest(vpt,&m,HITTYPE_POINT,0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); HitRecord *bestRec = rec; DWORD best = rec->distance; while(rec) { rec = rec->Next(); if(rec) { if(rec->distance < best) { best = rec->distance; bestRec = rec; } } } ShapeHitData *hit = ((ShapeHitData *)bestRec->hitData); es->HandleTrimExtend(vpt, hit, m, SHAPE_TRIM); } res = FALSE; break; case MOUSE_FREEMOVE: if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) { SetCursor(GetTransformCursor()); } else { SetCursor(LoadCursor(NULL,IDC_ARROW)); } break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
int BooleanMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; static int poly2 = -1; switch(msg) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: if(poly2 >= 0) if(ValidBooleanPolygon(es->ip, es->boolShape->splines[poly2])) es->DoBoolean(poly2); res = FALSE; break; case MOUSE_MOVE: case MOUSE_ABORT: res = FALSE; break; case MOUSE_FREEMOVE: poly2 = -1; if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); ShapeHitData *hit = ((ShapeHitData *)rec->hitData); Spline3D *spline = hit->shape->splines[hit->poly]; if(spline->Closed() && hit->shape == es->boolShape && hit->poly != es->boolPoly1) { poly2 = hit->poly; SetCursor(GetTransformCursor()); break; } } SetCursor(LoadCursor(NULL,IDC_ARROW)); break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
int CrossInsertMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; switch ( msg ) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: if(HitTest(vpt,&m,HITTYPE_POINT,0) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); ShapeHitData *h1 = (ShapeHitData *)rec->hitData; rec = rec->Next(); assert(rec); ShapeHitData *h2 = (ShapeHitData *)rec->hitData; assert(h1->shape == h2->shape); es->DoCrossInsert(vpt, h1->shape, h1->poly, h1->index, h2->poly, h2->index, m); } res = FALSE; break; case MOUSE_FREEMOVE: if ( HitTest(vpt,&m,HITTYPE_POINT,0) ) { SetCursor(GetTransformCursor()); } else { SetCursor(LoadCursor(NULL,IDC_ARROW)); } break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
static BOOL clipgrid(Point3 wp, ViewExp& vpt) { if ( ! vpt.IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } if(!vpt.IsPerspView()) return TRUE; float minx, miny, maxx, maxy; vpt.GetGridDims(&minx, &maxx, &miny, &maxy); if(wp.x > minx && wp.x < maxx && wp.y > miny && wp.y < maxy) return TRUE; return FALSE; }
void TrackMouseCallBack::draw_marker(ViewExp& vpt, Point3 p, Point3 norm) { return; // sorry, this doesn't work yet - I'll post it later // set GW tm to orientation specified by norm and draw a circle Matrix3 tm; Point3 zdir, ydir, xdir; // compute the direction of the z axis to be. // the positive z axis points AWAY from the target. zdir = Normalize(norm); // compute direction of the X axis before roll. xdir = Normalize(CrossProd(zdir.x > 0 ? Point3(0, 0, 1) : Point3(0, 0, -1), zdir)); // compute direction of the Y axis before roll. ydir = Normalize(CrossProd(zdir, xdir)); tm.SetRow(0, xdir); tm.SetRow(1, ydir); tm.SetRow(2, zdir); vpt.getGW()->setTransform(tm); vpt.getGW()->setColor(LINE_COLOR, MARKER_COLOR); vpt.getGW()->marker(&p, CIRCLE_MRKR); }
BOOL BoundsTree::HitQuadTree(IPoint2 m, int &nindex, DWORD &findex, Point3 &p, Point3 &norm, Point3 &bary, float &finalZ, Matrix3 &toWorldTm) { //int nindex = 0; Leaf *l = head; BOOL hit = FALSE; Point3 hitPoint(0.0f,0.0f,0.0f); DWORD smgroup; hitPoint.x = (float) m.x; hitPoint.y = (float) m.y; float z = 0.0f; Point3 bry; if (l == NULL) { z = 0.0f; return FALSE; } int ct = 0; while ( (l!=NULL) && (l->IsBottom() == FALSE)) { int id = l->InWhichQuad(hitPoint); l = l->GetQuad(id); ct++; } if (l) { if (l->faceIndex.Count() == 0) return FALSE; else { for (int i = 0; i < l->faceIndex.Count(); i++) { int faceIndex = l->faceIndex[i].faceIndex; int nodeIndex = l->faceIndex[i].nodeIndex; LightMesh *lmesh = meshList[nodeIndex]; Point3 *tempVerts = lmesh->vertsViewSpace.Addr(0); Face *tempFaces = lmesh->faces.Addr(faceIndex); Box2D b = lmesh->boundingBoxList[faceIndex]; if ( (hitPoint.x >= b.min.x) && (hitPoint.x <= b.max.x) && (hitPoint.y >= b.min.y) && (hitPoint.y <= b.max.y) ) { //now check bary coords Point3 a,b,c; a = tempVerts[tempFaces->v[0]]; b = tempVerts[tempFaces->v[1]]; c = tempVerts[tempFaces->v[2]]; Point3 az,bz,cz,hitPointZ; az = a; bz = b; cz = c; az.z = 0.0f; bz.z = 0.0f; cz.z = 0.0f; hitPointZ = hitPoint; hitPointZ.z = 0.0f; Point3 bry; bry = BaryCoords(az, bz, cz, hitPointZ); //if inside bary find the the z point if (!( (bry.x<0.0f || bry.x>1.0f || bry.y<0.0f || bry.y>1.0f || bry.z<0.0f || bry.z>1.0f) || (fabs(bry.x + bry.y + bry.z - 1.0f) > EPSILON) )) { float tz = a.z * bry.x + b.z * bry.y + c.z * bry.z; if ( (tz > z ) || (hit == FALSE) ) { z = tz; findex = faceIndex; nindex = nodeIndex; bary = bry; finalZ = z; smgroup = tempFaces->getSmGroup(); } hit = TRUE; } } } } } if (hit) { Point3 a,b,c; int ia,ib,ic; LightMesh *lmesh = meshList[nindex]; Point3 *tempVerts = lmesh->vertsWorldSpace.Addr(0); Face *tempFaces = lmesh->faces.Addr(findex); ia = tempFaces->v[0]; ib = tempFaces->v[1]; ic = tempFaces->v[2]; a = tempVerts[ia]; b = tempVerts[ib]; c = tempVerts[ic]; ViewExp *vpt = GetCOREInterface()->GetActiveViewport(); Ray worldRay; // vpt->GetAffineTM(tm); vpt->MapScreenToWorldRay((float) m.x, (float) m.y, worldRay); GetCOREInterface()->ReleaseViewport(vpt); //intersect ray with the hit face // See if the ray intersects the plane (backfaced) norm = Normalize((b-a)^(c-b)); float rn = DotProd(worldRay.dir,norm); // Use a point on the plane to find d float d = DotProd(a,norm); // Find the point on the ray that intersects the plane float ta = (d - DotProd(worldRay.p,norm)) / rn; // The point on the ray and in the plane. p = worldRay.p + ta*worldRay.dir; // Compute barycentric coords. bary = BaryCoords(a, b, c, p); finalZ = ta; // p = a * bary.x + b * bary.y + c * bary.z; p = p * meshList[nindex]->toLocalSpace; norm = VectorTransform(meshList[nindex]->toLocalSpace,norm); toWorldTm = meshList[nindex]->toWorldSpace; } return hit; }
/** * This method will be called from the max system when the user * has choosen to export to the OpenSceneGraph format. * This method is the entry point to the exporter plugin. */ int OSGExp::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD MAXOptions){ // Only support "one at the time" exporting. if(isExporting){ return FALSE; } isExporting = TRUE; // Grab the interface pointer and save it for later use. _ip = i; // Set export path in options class TCHAR p[300]; TCHAR f[100]; TCHAR e[10]; BMMSplitFilename(name, p, f, e); _options->setExportPath(p); _options->setExportFilename(f); _options->setExportExtension(e); // Get filename to config file. TSTR cfgfilename = _ip->GetDir(APP_PLUGCFG_DIR);; cfgfilename += _T("\\OSGEXP.CFG"); // Load options from config file _options->load(cfgfilename); // Should we only export selected nodes? _onlyExportSelected = (MAXOptions & SCENE_EXPORT_SELECTED) ? TRUE : FALSE; // Show option dialog to user and retrive any possible plugin choices. if(!suppressPrompts) if(!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EXPORTBOX), GetActiveWindow(), OptionsDlgProc, (LPARAM)_options)){ // If user closed or canceled export box then shutdown plugin. isExporting = FALSE; return TRUE; } // Write options to config file. _options->write(cfgfilename); // Create OSG root transform to hold the scene. { osg::ref_ptr<osg::MatrixTransform> rootTransform = new osg::MatrixTransform(); //osg::MatrixTransform* rootTransform = new osg::MatrixTransform(); rootTransform->setName(std::string(_ip->GetRootNode()->GetName())); // Set static datavariance for better performance rootTransform->setDataVariance(osg::Object::STATIC); // Set NodeMask if(_options->getUseDefaultNodeMaskValue()) rootTransform->setNodeMask(_options->getDefaultNodeMaskValue()); osg::Matrix rootMat = getNodeTransform(_ip->GetRootNode(), _ip->GetTime()); rootTransform->setMatrix(rootMat); // Create root stateset for the lights. osg::ref_ptr<osg::StateSet> rootStateSet = new osg::StateSet(); // Turn of lighting if set by the user. if(_options->getTurnOffLighting()) rootStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF); else rootStateSet->setMode(GL_LIGHTING,osg::StateAttribute::ON); //osg::StateSet* rootStateSet = new osg::StateSet(); rootTransform->setStateSet(rootStateSet.get()); // We will make two progress bars. The first one will show // the exporting of materials, wheras the second one will show // the exporting of nodes. To get the total number of nodes in the // scene graph we will accumulate the total node count while // preprocessing the scenegraph for materials. _nTotalNodeCount = 0; _nCurNode = 0; _nTotalMtlCount = _ip->GetSceneMtls()->Count(); _nCurMtl = 0; // Starting up the material exporting progress bar. _ip->ProgressStart(_T("Exporting materials..."), TRUE, fn, NULL); // Export materials by preprocessing the scenegraph. if(!preProcess(_ip->GetRootNode(), _ip->GetTime())){ // If user cancels we stop progress bar and return. _ip->ProgressEnd(); isExporting = FALSE; return TRUE; } // We're done exporting materials. Finish the progress bar. _ip->ProgressEnd(); // Starting up the node exporting progress bar. _ip->ProgressStart(_T("Exporting scene..."), TRUE, fn, NULL); // Get number of children for the root node in the interface. int numChildren = _ip->GetRootNode()->NumberOfChildren(); // Call our node enumerator. // The nodeEnum function will recurse into itself and // export each object found in the scene. for (int idx=0; idx<numChildren; idx++) { if (_ip->GetCancel() || !nodeEnum(rootTransform.get(), _ip->GetRootNode()->GetChildNode(idx), rootTransform.get())){ // If user cancels we stop progress bar and return _ip->ProgressEnd(); isExporting = FALSE; return TRUE; } } // Finish exporting progress bar _ip->ProgressEnd(); // If optimize scene graph unsigned int optimizeMask = 0; if(_options->getTriStripGeometry()) optimizeMask |= osgUtil::Optimizer::TRISTRIP_GEOMETRY; if(_options->getMergeGeometry()) optimizeMask |= osgUtil::Optimizer::MERGE_GEOMETRY; if(_options->getFlattenStaticTransform()) optimizeMask |= osgUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS; if(_options->getShareDuplicateStates()) optimizeMask |= osgUtil::Optimizer::SHARE_DUPLICATE_STATE; if(_options->getSpatializeGroups()) optimizeMask |= osgUtil::Optimizer::SPATIALIZE_GROUPS; if(optimizeMask){ _ip->ProgressStart(_T("Optimizing scenegraph..."), FALSE, fn, NULL); _ip->ProgressUpdate(0.5f); osgUtil::Optimizer optimizer; optimizer.optimize(rootTransform.get(), optimizeMask); _ip->ProgressEnd(); } // Save file to disk. if(_options->getSaveFile()){ _ip->ProgressStart(_T("Writing file..."), FALSE, fn, NULL); _ip->ProgressUpdate(0.5f); if(_options->getExportExtension().compare(".osg")==0 || _options->getExportExtension().compare(".OSG")==0 || _options->getExportExtension().compare(".ive")==0 || _options->getExportExtension().compare(".IVE")==0 ){ std::string filename(name); // Exclude image data from ive file if this options has been choosen if(!_options->getIncludeImageDataInIveFile()){ osgDB::ReaderWriter::Options* opt = new osgDB::ReaderWriter::Options("noTexturesInIVEFile"); osgDB::Registry::instance()->setOptions(opt); } #if defined(OPENSCENEGRAPH_MAJOR_VERSION) && OPENSCENEGRAPH_MAJOR_VERSION >= 2 && defined(OPENSCENEGRAPH_MINOR_VERSION) && OPENSCENEGRAPH_MINOR_VERSION >= 4 osgDB::ReaderWriter::WriteResult res = osgDB::Registry::instance()->writeNode(*rootTransform, filename, NULL); #else osgDB::ReaderWriter::WriteResult res = osgDB::Registry::instance()->writeNode(*rootTransform, filename); #endif if(res.error() && _options->getShowErrMsg()){ static TCHAR szBuffer[256]; wsprintf(szBuffer,TEXT("Error writing file %s:\n%s"), TEXT(filename.c_str()),res.message()); MessageBox (GetActiveWindow(), szBuffer, TEXT("Warning"), MB_OK | MB_ICONWARNING) ; } if(!_options->getIncludeImageDataInIveFile()){ // Turn readerwriter options off again. osgDB::ReaderWriter::Options* opt = new osgDB::ReaderWriter::Options(); osgDB::Registry::instance()->setOptions(opt); } } else{ if(_options->getShowErrMsg()){ std::string error("Can not find plugin to save file: "); error.append(name); MessageBox (GetActiveWindow(), error.c_str() , TEXT("Warning"), MB_OK | MB_ICONWARNING) ; } } _ip->ProgressEnd(); } // Show quick preview if(_options->getQuickView()){ float fNear = 1.0f; float fFar = 1000.0f; // Get the active viewport and the win32 window within it. // The position and size will be retreive from this. ViewExp* viewExp = _ip->GetActiveViewport(); float fov = viewExp->GetFOV(); HWND hWnd = viewExp->getGW()->getHWnd(); RECT sRect; BOOL ok = GetWindowRect(hWnd, &sRect); int width = 100; int height = 100; int x =100; int y =100; if(ok){ x = sRect.left; y = sRect.top; width = sRect.right - sRect.left; height = sRect.bottom - sRect.top; } // Create previewer window and set size. Previewer previewer; previewer.setWindowSize(x, y, width, height); // The affine TM transforms from world coords to view coords // so we need the inverse of this matrix Matrix3 aTM, camTM, coordSysTM; Point3 viewDir, viewPos, lookAtPos, upVector; INode* camera; float dist = 100; Point3 upperLeft = viewExp->MapScreenToView(IPoint2(0, 0), fFar); Point3 lowerRight = viewExp->MapScreenToView(IPoint2(width, height), fFar); viewExp->GetAffineTM(aTM); coordSysTM = Inverse(aTM); viewDir = coordSysTM.VectorTransform(Point3(0.0f, 0.0f, -1.0f)); viewPos = coordSysTM.GetRow(3); lookAtPos = viewPos + viewDir; upVector.Set(0.0f, 0.0f, 1.0f); switch(viewExp->GetViewType()){ case VIEW_ISO_USER: case VIEW_PERSP_USER: previewer.setProjectionMatrixAsFrustum(lowerRight.x, upperLeft.x, upperLeft.y, lowerRight.y, fFar, -fFar); break; case VIEW_CAMERA: previewer.setProjectionMatrixAsFrustum(upperLeft.x, lowerRight.x, lowerRight.y, upperLeft.y, fFar, -fFar); camera = viewExp->GetViewCamera(); camTM = camera->GetObjTMBeforeWSM(_ip->GetTime()); viewDir = camTM.VectorTransform(Point3(0.0f, 0.0f, -1.0f)); viewPos = camTM.GetRow(3); lookAtPos = viewPos + viewDir; break; case VIEW_LEFT: case VIEW_RIGHT: case VIEW_TOP: case VIEW_BOTTOM: case VIEW_FRONT: case VIEW_BACK: previewer.setProjectionMatrixAsOrtho(upperLeft.x, lowerRight.x, lowerRight.y, upperLeft.y, -fFar, fFar); //cam->setOrtho(upperLeft.x, lowerRight.x, lowerRight.y, upperLeft.y, -fFar, fFar); // Go far away from the viewing point in the negative viewing direction. viewPos = coordSysTM.PointTransform(Point3(0.0f, 0.0f, fFar)); lookAtPos = viewPos + viewDir; // In top view the up vector on the camera is the positive y-axis. if(viewExp->GetViewType() == VIEW_TOP) upVector.Set(0.0f, 1.0f, 0.0f); // In bottom view the up vector on the camera is the negative y-axis. if(viewExp->GetViewType() == VIEW_BOTTOM) upVector.Set(0.0f, -1.0f, 0.0f); break; } // When we are done with the viewport we should release it. _ip->ReleaseViewport(viewExp); // Set scene data. previewer.setSceneData(rootTransform.get()); // set the view - OpenGL look at previewer.setViewMatrixAsLookAt(osg::Vec3( viewPos.x, viewPos.y, viewPos.z), osg::Vec3(lookAtPos.x, lookAtPos.y, lookAtPos.z), osg::Vec3(upVector.x, upVector.y, upVector.z) ); previewer.run(); isExporting = FALSE; return TRUE; } } isExporting = FALSE; return TRUE; }
void TweakMouseProc::ComputeNewUVW(ViewExp& vpt, IPoint2 m) { if ( ! vpt.IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return; } Ray r; vpt.MapScreenToWorldRay ((float) m.x, (float) m.y, r); TimeValue t = GetCOREInterface()->GetTime(); Matrix3 tm = mod->GetMeshTopoDataNode(mHitLDIndex)->GetObjectTM(t); Matrix3 itm = Inverse(tm); r.p = r.p * itm; r.dir = VectorTransform(r.dir,itm); //intersect our ray with that face and get our new bary coords Point3 n = mHitLD->GetGeomFaceNormal(mHitFace); Point3 p1, p2, p3; p1 = mHitP[0]; p2 = mHitP[1]; p3 = mHitP[2]; Point3 p, bry; float d, rn, a; // See if the ray intersects the plane (backfaced) rn = DotProd(r.dir,n); if (rn > -0.0001) return; // Use a point on the plane to find d Point3 v1 = p1; d = DotProd(v1,n); // Find the point on the ray that intersects the plane a = (d - DotProd(r.p,n)) / rn; // Must be positive... if (a < 0.0f) return ; // The point on the ray and in the plane. p = r.p + a*r.dir; // Compute barycentric coords. bry = BaryCoords(p1,p2,p3,p); // DbgAssert(bry.x + bry.y+ bry.z = 1.0) Point3 uvw = mHitUVW[0] * bry.x + mHitUVW[1] * bry.y + mHitUVW[2] * bry.z; Point3 v = uvw - mSourceUVW; v *= -1.0f; mFinalUVW = mSourceUVW + v; mHitLD->SetTVVert(GetCOREInterface()->GetTime(),mHitTVVert,mFinalUVW,mod); mod->NotifyDependents(FOREVER, PART_TEXMAP, REFMSG_CHANGE); mod->InvalidateView(); if (mod->ip) mod->ip->RedrawViews(mod->ip->GetTime()); }
BOOL TrackMouseCallBack::point_on_obj(ViewExp& vpt, IPoint2 m, Point3& pt, Point3 &norm) { if ( ! vpt.IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } // computes the normal ray at the point of intersection Ray ray, world_ray; float at, best_dist = 0.0f; TimeValue t = MAXScript_time(); Object *obj = NULL; Matrix3 obtm, iobtm; Point3 testNorm; BOOL found_hit = FALSE; vl->face_num_val = vl->face_bary = &undefined; hit_node = NULL; // Calculate a ray from the mouse point vpt.MapScreenToWorldRay(float(m.x), float(m.y), world_ray); for( int i=(nodeTab.Count()-1); i>=0; i-- ) { // Get the object from the node INode* node = nodeTab[i]; ObjectState os = node->EvalWorldState(t); obj = os.obj; // Back transform the ray into object space. obtm = node->GetObjectTM(t); iobtm = Inverse(obtm); ray.p = iobtm * world_ray.p; ray.dir = VectorTransform(iobtm, world_ray.dir); // See if we hit the object if (obj->IsSubClassOf(triObjectClassID)) { TriObject* tobj = (TriObject*)obj; DWORD fi; Point3 bary; if (tobj->mesh.IntersectRay(ray, at, testNorm, fi, bary) && ((!found_hit) || (at<=best_dist)) ) { // Calculate the hit point and transform everything back into world space. // record the face index and bary coord best_dist = at; pt = ray.p + ray.dir * at; pt = pt * obtm; norm = Normalize(VectorTransform(obtm, testNorm)); vl->face_num_val = Integer::intern(fi + 1); vl->face_bary = new Point3Value(bary); hit_node = node; found_hit = TRUE; } } else if (obj->IntersectRay(t, ray, at, testNorm) && ((!found_hit) || (at<=best_dist)) ) { // Calculate the hit point and transform everything back into world space. best_dist = at; pt = ray.p + ray.dir * at; pt = pt * obtm; norm = Normalize(VectorTransform(obtm, testNorm)); hit_node = node; found_hit = TRUE; } } if( found_hit ) return TRUE; // Failed to find a hit on any node, look at the Normal Align Vector for the first node if ((obj!=NULL) && obj->NormalAlignVector(t, pt, testNorm)) // See if a default NA vector is provided { pt = pt * obtm; norm = Normalize(VectorTransform(obtm, testNorm)); return TRUE; } else return FALSE; }
int CreateLineMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; static int poly, seg, vert; static BezierShape *shape; static Spline3D *spline; static BOOL creating = FALSE; static BOOL inserting = FALSE; static Matrix3 mat; static EditSplineMod *mod; static int originalInsert; if(creating) { // Ignore the messages the spline code doesn't care about... TH 3/12/99 switch(msg) { #ifdef DESIGN_VER case MOUSE_DBLCLICK: #endif case MOUSE_POINT: case MOUSE_MOVE: case MOUSE_ABORT: break; default: return TRUE; } vpt->getGW()->setTransform(mat); int res = shape->splines[poly]->Create(vpt,msg,point,flags,m,&mat,ip); // Must update the shape's selection set for this spline shape->UpdateSels(TRUE); switch(res) { case CREATE_STOP: es->EndCreateLine(); creating = FALSE; backspaceRouter.UnRegister(&pBack); break; case CREATE_ABORT: shape->DeleteSpline(poly); es->EndCreateLine(FALSE); creating = FALSE; backspaceRouter.UnRegister(&pBack); break; } mod->createShapeData->Invalidate(PART_GEOM); mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); } else if(inserting) { // Ignore the messages the spline code doesn't care about... TH 3/12/99 switch(msg) { #ifdef DESIGN_VER case MOUSE_DBLCLICK: #endif case MOUSE_POINT: { for (int i = 0; i < shape->bindList.Count();i++) { if (poly == shape->bindList[i].segSplineIndex) { if ((seg!=-1)&&(originalInsert <= shape->bindList[i].seg)) { if (originalInsert == shape->bindList[i].seg) { { shape->bindList[i].seg++; } } else { shape->bindList[i].seg++; } } } } } case MOUSE_MOVE: case MOUSE_ABORT: break; default: return TRUE; } int res = shape->splines[poly]->Create(vpt,msg,point,flags,m,&mat,ip); // Must update the shape's selection set for this spline BitArray& vsel = shape->vertSel[poly]; BitArray& ssel = shape->segSel[poly]; while(vsel.GetSize() < shape->splines[poly]->Verts()) { vsel.SetSize(vsel.GetSize() + 3,1); vsel.Shift(RIGHT_BITSHIFT,3,vert+3); vsel.Clear(vert+2); vsel.Clear(vert+3); vsel.Clear(vert+4); } while(ssel.GetSize() < shape->splines[poly]->Segments()) { ssel.SetSize(ssel.GetSize() + 1,1); ssel.Shift(RIGHT_BITSHIFT,1,vert/3+1); ssel.Clear(vert/3+1); } switch(res) { case CREATE_STOP: { // Must update the shape's selection set for this spline BitArray& vsel = shape->vertSel[poly]; BitArray& ssel = shape->segSel[poly]; while(vsel.GetSize() > shape->splines[poly]->Verts()) { vsel.Shift(LEFT_BITSHIFT,3,vert+1); vsel.SetSize(vsel.GetSize() - 3,1); } while(ssel.GetSize() > shape->splines[poly]->Segments()) { ssel.Shift(LEFT_BITSHIFT,1,(vert+1)/3); ssel.SetSize(ssel.GetSize() - 1,1); } es->EndVertInsert(); inserting = FALSE; backspaceRouter.UnRegister(&iBack); for (int i = 0; i < shape->bindList.Count();i++) { if (poly == shape->bindList[i].segSplineIndex) { if ((seg!=-1)&&(originalInsert <= shape->bindList[i].seg)) { if (originalInsert == shape->bindList[i].seg) { { shape->bindList[i].seg--; } } else { shape->bindList[i].seg--; } } } } break; } case CREATE_ABORT: shape->DeleteSpline(poly); es->insertPoly = -1; es->EndVertInsert(); inserting = FALSE; backspaceRouter.UnRegister(&iBack); break; } mod->insertShapeData->Invalidate(PART_GEOM); mod->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); } else { switch(msg) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: mod = es; if((SplineShape::GetUseEndPointAutoConnect()==BST_CHECKED) && InsertWhere(vpt, &m, &shape, &poly, &seg, &vert)) { vert = es->StartVertInsert(vpt, shape, poly, seg, vert, &mod); if(vert < 0) { res = FALSE; break; } originalInsert = seg; mat = mod->insertTM; shape->splines[poly]->StartInsert(vpt, msg, point, flags, m, &mat, vert/3+1 ); // Must update the shape's selection set for this spline BitArray& vsel = shape->vertSel[poly]; BitArray& ssel = shape->segSel[poly]; while(vsel.GetSize() < shape->splines[poly]->Verts()) { vsel.SetSize(vsel.GetSize() + 3,1); vsel.Shift(RIGHT_BITSHIFT,3,vert+3); vsel.Clear(vert+2); vsel.Clear(vert+3); vsel.Clear(vert+4); } while(ssel.GetSize() < shape->splines[poly]->Segments()) { ssel.SetSize(ssel.GetSize() + 1,1); ssel.Shift(RIGHT_BITSHIFT,1,vert/3+1); ssel.Clear(vert/3+1); } inserting = TRUE; iBack.SetPtrs(mod, shape->splines[poly]); backspaceRouter.Register(&iBack); } else { if(!mod->StartCreateLine(&shape)) return CREATE_ABORT; poly = shape->splineCount; spline = shape->NewSpline(); shape->UpdateSels(TRUE); mat = mod->createTM; vpt->getGW()->setTransform(mat); if(spline->Create(vpt,msg,point,flags,m,&mat,ip) == CREATE_CONTINUE) { creating = TRUE; shape->UpdateSels(TRUE); pBack.SetPtrs(mod, spline); backspaceRouter.Register(&pBack); } else { shape->DeleteSpline(poly); res = FALSE; } } SetCursor(LoadCursor(hInstance,MAKEINTRESOURCE(IDC_ES_CROSS_HAIR))); break; case MOUSE_MOVE: case MOUSE_ABORT: res = FALSE; break; case MOUSE_FREEMOVE: if((SplineShape::GetUseEndPointAutoConnect()==BST_CHECKED) && InsertWhere(vpt, &m, &shape, &poly, &seg, &vert)) SetCursor(LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CREATE_WELD))); else SetCursor(LoadCursor(hInstance,MAKEINTRESOURCE(IDC_ES_CROSS_HAIR))); vpt->SnapPreview(m,m,NULL, SNAP_IN_3D); break; } } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
int VertConnectMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { ViewExp *vpt = ip->GetViewport(hwnd); int res = TRUE; static BezierShape *shape1 = NULL; static int poly1, vert1, poly2, vert2; static IPoint2 anchor, lastPoint; switch ( msg ) { case MOUSE_PROPCLICK: ip->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_POINT: switch(point) { case 0: if(HitAnEndpoint(vpt, &m, NULL, -1, -1, &shape1, &poly1, &vert1)) res = TRUE; else res = FALSE; anchor = lastPoint = m; XORDottedLine(hwnd, anchor, m); // Draw it! break; case 1: XORDottedLine(hwnd, anchor, lastPoint); // Erase it! if(HitAnEndpoint(vpt, &m, shape1, poly1, vert1, NULL, &poly2, &vert2)) es->DoVertConnect(vpt, shape1, poly1, vert1, poly2, vert2); res = FALSE; break; default: assert(0); } break; case MOUSE_MOVE: // Erase old dotted line XORDottedLine(hwnd, anchor, lastPoint); // Draw new dotted line XORDottedLine(hwnd, anchor, m); lastPoint = m; if(HitAnEndpoint(vpt, &m, shape1, poly1, vert1, NULL, NULL, NULL)) SetCursor(GetTransformCursor()); else SetCursor(LoadCursor(NULL,IDC_ARROW)); break; case MOUSE_FREEMOVE: if ( HitTest(vpt,&m,HITTYPE_POINT,HIT_ABORTONHIT) ) { HitLog &hits = vpt->GetSubObjHitList(); HitRecord *rec = hits.First(); ShapeHitData *hit = ((ShapeHitData *)rec->hitData); Spline3D *spline = hit->shape->splines[hit->poly]; if(!spline->Closed()) { int hitKnot = hit->index / 3; if(hitKnot == 0 || hitKnot == (spline->KnotCount() - 1)) { SetCursor(LoadCursor(hInstance,MAKEINTRESOURCE(IDC_TH_SELCURSOR))); break; } } } SetCursor(LoadCursor(NULL,IDC_ARROW)); break; case MOUSE_ABORT: // Erase old dotted line XORDottedLine(hwnd, anchor, lastPoint); break; } if ( vpt ) ip->ReleaseViewport(vpt); return res; }
// ***************************************************************** void VertexPaint::fillSelectionGradientColor() { int mci; // Put Data in Undo/Redo List. if(!theHold.Holding()) theHold.Begin(); ModContextList modContexts; INodeTab nodeTab; GetCOREInterface()->GetModContexts(modContexts, nodeTab); for (mci=0; mci<modContexts.Count(); mci++) { ModContext *mc = modContexts[mci]; if(mc && mc->localData) theHold.Put(new VertexPaintRestore((VertexPaintData*)mc->localData, this)); } theHold.Accept(GetString(IDS_RESTORE_GRADIENT)); // Which Component to change?? VertexPaintData::TComponent whichComponent; switch(getEditionType()) { case 0: whichComponent= VertexPaintData::Red; break; case 1: whichComponent= VertexPaintData::Green; break; case 2: whichComponent= VertexPaintData::Blue; break; } COLORREF grad0= iColorGradient[0]->GetColor(); COLORREF grad1= iColorGradient[1]->GetColor(); // Get Matrix to viewport. Matrix3 viewMat; { ViewExp *ve = GetCOREInterface()->GetActiveViewport(); // The affine TM transforms from world coords to view coords ve->GetAffineTM(viewMat); GetCOREInterface()->ReleaseViewport(ve); } // Modify all meshes. for (mci=0; mci<modContexts.Count(); mci++) { ModContext *mc = modContexts[mci]; if(mc && mc->localData) { VertexPaintData* d = (VertexPaintData*)mc->localData; Mesh* mesh = d->GetMesh(); if (mesh && mesh->vertCol) { float yMini= FLT_MAX; float yMaxi= -FLT_MAX; // 1st, For all faces of the mesh, comute BBox of selection. int fi; for(fi=0; fi<mesh->getNumFaces(); fi++) { Face* f = &mesh->faces[fi]; for (int i=0; i<3; i++) { // Skip painting because not selected?? if(mesh->selLevel == MESH_VERTEX && !mesh->VertSel()[f->v[i]] ) continue; if(mesh->selLevel == MESH_FACE && !mesh->FaceSel()[fi]) continue; // Also skip if face is hidden. if(f->Hidden()) continue; // Transform to viewSpace. Point3 p= viewMat*mesh->getVert(f->v[i]); // extend bbox. yMini= p.y<yMini?p.y:yMini; yMaxi= p.y>yMaxi?p.y:yMaxi; } } // 2nd, For all faces of the mesh, fill with gradient for(fi=0; fi<mesh->getNumFaces(); fi++) { Face* f = &mesh->faces[fi]; for (int i=0; i<3; i++) { // Skip painting because not selected?? if(mesh->selLevel == MESH_VERTEX && !mesh->VertSel()[f->v[i]] ) continue; if(mesh->selLevel == MESH_FACE && !mesh->FaceSel()[fi]) continue; // Also skip if face is hidden. if(f->Hidden()) continue; // Compute gradientValue. float gradValue; Point3 p= viewMat*mesh->getVert(f->v[i]); gradValue= (p.y-yMini)/(yMaxi-yMini); // Modifie with bendPower. 1->6. float pow= 1 + fGradientBend * 5; gradValue= powf(gradValue, pow); // Apply painting // Reset To 0. d->SetColor(f->v[i], 1, grad0, whichComponent); // Blend with gradientValue. d->SetColor(f->v[i], gradValue, grad1, whichComponent); } } } } } // refresh NotifyDependents(FOREVER, PART_VERTCOLOR, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); }
int CreateSWrapObjectProc::proc(HWND hwnd,int msg,int point,int flag, IPoint2 m ) { int res=TRUE; ViewExp *vpx = createInterface->GetViewport(hwnd); assert( vpx ); #ifdef _3D_CREATE DWORD snapdim = SNAP_IN_3D; #else DWORD snapdim = SNAP_IN_PLANE; #endif switch ( msg ) { case MOUSE_POINT: switch ( point ) { case 0: assert( SWrapObj ); vpx->CommitImplicitGrid(m, flag ); if ( createInterface->SetActiveViewport(hwnd) ) { return FALSE; } if (createInterface->IsCPEdgeOnInView()) { res = FALSE; goto done; } if ( attachedToNode ) { // send this one on its way #ifdef _OSNAP SWrapObj->ClearAFlag(A_OBJ_LONG_CREATE); #endif SWrapObj->EndEditParams( (IObjParam*)createInterface, 0, NULL); if (SWrapNode) { theHold.Suspend(); DeleteReference(0); theHold.Resume(); } // new object CreateNewObject(); // creates SWrapObj } theHold.Begin(); // begin hold for undo mat.IdentityMatrix(); // link it up SWrapNode = createInterface->CreateObjectNode( SWrapObj); attachedToNode = TRUE; assert( SWrapNode ); createCB = NULL; createInterface->SelectNode( SWrapNode ); // Reference the new node so we'll get notifications. theHold.Suspend(); MakeRefByID( FOREVER, 0, SWrapNode); theHold.Resume(); mat.IdentityMatrix(); default: res = createmethod(vpx,msg,point,flag,m,mat); createInterface->SetNodeTMRelConstPlane(SWrapNode, mat); if (res==CREATE_ABORT) goto abort; if (res==CREATE_STOP){ #ifdef _OSNAP SWrapObj->ClearAFlag(A_OBJ_LONG_CREATE); #endif theHold.Accept(GetString(IDS_AP_CREATE)); } createInterface->RedrawViews(createInterface->GetTime()); break; } break; case MOUSE_MOVE: res = createmethod(vpx,msg,point,flag,m,mat); createInterface->SetNodeTMRelConstPlane(SWrapNode, mat); if (res==CREATE_ABORT) goto abort; if (res==CREATE_STOP){ #ifdef _OSNAP SWrapObj->ClearAFlag(A_OBJ_LONG_CREATE); #endif theHold.Accept(GetString(IDS_AP_CREATE)); } createInterface->RedrawViews(createInterface->GetTime()); break; /* res = createmethod(vpx,msg,point,flag,m,mat); createInterface->SetNodeTMRelConstPlane(SWrapNode, mat); if (res==CREATE_ABORT) goto abort; if (res==CREATE_STOP) theHold.Accept(GetString(IDS_AP_CREATE)); createInterface->RedrawViews(createInterface->GetTime()); break;*/ case MOUSE_PROPCLICK: createInterface->SetStdCommandMode(CID_OBJMOVE); break; case MOUSE_ABORT: abort: assert( SWrapObj ); #ifdef _OSNAP SWrapObj->ClearAFlag(A_OBJ_LONG_CREATE); #endif SWrapObj->EndEditParams( (IObjParam*)createInterface,0,NULL); theHold.Cancel(); // deletes both the object and target. if (theHold.GetGlobalPutCount()!=lastPutCount) GetSystemSetting(SYSSET_CLEAR_UNDO); SWrapNode = NULL; createInterface->RedrawViews(createInterface->GetTime()); CreateNewObject(); attachedToNode = FALSE; res = FALSE; break; case MOUSE_FREEMOVE: SetCursor(LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CROSS_HAIR))); #ifdef _OSNAP //PREVIEW SNAP res = createmethod(vpx,msg,point,flag,m,mat); #endif vpx->TrackImplicitGrid(m); break; } done: if ((res == CREATE_STOP)||(res==CREATE_ABORT)) vpx->ReleaseImplicitGrid(); createInterface->ReleaseViewport(vpx); return res; }
void gridSnap::Snap(Object* pobj, IPoint2 *p, TimeValue t) { ViewExp *vpt = theman->GetVpt(); if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return; } DbgAssert(vpt != NULL); //local copy of the cursor position Point2 fp = Point2((float)p->x, (float)p->y); BOOL got_one= FALSE; //Get point on the consttruction plane Point3 local_cp = vpt->GetPointOnCP(*p); Point3 world_snapped; Matrix3 tmconst; vpt->GetConstructionTM( tmconst ); // aszabo|nov.01.05|#596889, #613720, #703875 // In order to allow snapping to the grid sub-divisions computed based on viewport // the zoom facto, the grid spacing is taken from the viewport. // When the grid is invisible and the zoom factor changes, the viewport returns // the grid spacing computed last time the grid was displayed. // When max starts up with hidden grids (via maxstart.max), the viewport's grid // spacing will be zero and in that case we take the grid spacing value specified // in the Grid setting UI. float gridSpacing = vpt->GetGridSize(); if (!(gridSpacing > 0.0f || gridSpacing < 0.0f)) { gridSpacing = GetCOREInterface()->GetGridSpacing(); } //Compute all the hit point candidates if( GetActive(INT_SUB)) { float gridZ = 0.f; #ifdef GAME_VER float gridSpacing = GetCOREInterface()->GetGridSpacing(); SnapInfo si; GetCOREInterface()->InitSnapInfo(&si); if(si.snapType == SNAP_25D) gridZ = GridCoord(local_cp.z,gridSpacing); Point3 intsnapped = Point3(GridCoord(local_cp.x,gridSpacing),GridCoord(local_cp.y,gridSpacing),gridZ); world_snapped = tmconst * intsnapped;//now in world space got_one = TRUE; hitmesh = new HitMesh(5); hitmesh->setVert(0,tmconst * Point3(intsnapped.x,intsnapped.y - gridSpacing,gridZ)); hitmesh->setVert(1,tmconst * Point3(intsnapped.x,intsnapped.y + gridSpacing,gridZ)); hitmesh->setVert(2,tmconst * Point3(intsnapped.x-gridSpacing,intsnapped.y,gridZ)); hitmesh->setVert(3,tmconst * Point3(intsnapped.x + gridSpacing,intsnapped.y,gridZ)); //now register a hit with the osnap manager //possibly screen for proximity to the foreground theman->RecordHit(new OsnapHit(world_snapped, this, INT_SUB, hitmesh)); #else //!GAME_VER // aszabo|sep.15.04|#596889|The gridSpacing spacing shouldn't be zero, but if it is, it can lead to infinite loops DbgAssert(gridSpacing > 0.0f || gridSpacing < 0.0f); if (gridSpacing > 0.0f || gridSpacing < 0.0f) { // Record all hits that fall in the snap preview area. // Grids are infinite, so we can't loop through their "vertexes". // Instead go through only those that are potential snap points, by starting // at the closest grid point to the mouse and extending in all directions // using "grid size" steps. Point3 intsnapped = Point3(GridCoord(local_cp.x,gridSpacing),GridCoord(local_cp.y,gridSpacing),gridZ); Point3 curIntsnapped(intsnapped); world_snapped = tmconst * intsnapped; // set the window transform to identity to guarantee a world-screen transformation. if (theman->GetVpt() && theman->GetVpt()->getGW()) { theman->GetVpt()->getGW()->setTransform(Matrix3(TRUE)); } // Find all snap points on the right side (positive x) of the intsnapped, including the intsnapped while (CheckPotentialHit(&world_snapped,0, fp)) { got_one = TRUE; RecordNewIntSubHit(world_snapped, tmconst, curIntsnapped, gridSpacing); //ktong|Jan.27.2006|#748560|Limit the number of snap points to search only visibly distinct points. // If the grid point is too far away to tell it from the next gridpoint, stop searching. // No point in enumerating snap points a user can't visibly tell apart. // Check after the first snap point (the closest) is registered to at least have one. if (TooDistant(theman, world_snapped, gridSpacing)) { break; } // Go down the vertical grid line curIntsnapped.y -= gridSpacing; FindVerticalIntSubHit(tmconst, curIntsnapped, fp, (-gridSpacing)); // Go up the vertical grid line curIntsnapped.y = intsnapped.y + gridSpacing; FindVerticalIntSubHit(tmconst, curIntsnapped, fp, gridSpacing); // Go to the right of the original vertival grid line curIntsnapped.y = intsnapped.y; curIntsnapped.x += gridSpacing; world_snapped = tmconst * curIntsnapped; } // Find all snap points on the left side (negative x) of the intsnapped curIntsnapped.y = intsnapped.y; curIntsnapped.x = intsnapped.x - gridSpacing; world_snapped = tmconst * curIntsnapped; //ktong|Jan.27.2006|#748560|Limit the number of snap points to search only visibly distinct points. while (CheckPotentialHit(&world_snapped,0, fp) && !TooDistant(theman, world_snapped, gridSpacing) ) { got_one = TRUE; RecordNewIntSubHit(world_snapped, tmconst, curIntsnapped, gridSpacing); // Go down the vertical grid line curIntsnapped.y -= gridSpacing; FindVerticalIntSubHit(tmconst, curIntsnapped, fp, (-gridSpacing)); // Go up the vertical grid line curIntsnapped.y = intsnapped.y + gridSpacing; FindVerticalIntSubHit(tmconst, curIntsnapped, fp, gridSpacing); // Go to the right of the original vertival grid line curIntsnapped.y = intsnapped.y; curIntsnapped.x -= gridSpacing; world_snapped = tmconst * curIntsnapped; } } #endif //GAME_VER } if( GetActive(EDGE_SUB) && !got_one) { BOOL snapx = FALSE; float xSnap = GridCoord(local_cp.x,gridSpacing); float ySnap = GridCoord(local_cp.y,gridSpacing); float xDist = (float)fabs(xSnap - local_cp.x); float yDist = (float)fabs(ySnap - local_cp.y); Point3 esnapped; // Which one is closer? if(xDist < yDist) { snapx = TRUE; esnapped = Point3(xSnap,local_cp.y,0.0f); } else { esnapped = Point3(local_cp.x,ySnap,0.0f); } world_snapped = tmconst * esnapped;//now in world space if (CheckPotentialHit(&world_snapped,0, fp)) { if(clipgrid(world_snapped, *vpt)) { got_one = TRUE; HitMesh* hitmesh = new HitMesh(3); if(snapx) { hitmesh->setVert(0,tmconst * Point3(esnapped.x,esnapped.y - gridSpacing,0.0f)); hitmesh->setVert(1,tmconst * Point3(esnapped.x,esnapped.y + gridSpacing,0.0f)); } else { hitmesh->setVert(0,tmconst * Point3(esnapped.x - gridSpacing, esnapped.y,0.0f)); hitmesh->setVert(1,tmconst * Point3(esnapped.x + gridSpacing, esnapped.y,0.0f)); } theman->RecordHit(new OsnapHit(world_snapped, this, EDGE_SUB, hitmesh)); } } } }