void FskClipPolygon2D( UInt32 nIn, register FskFixedPoint2D *vIn, FskConstRectangle clip, UInt32 *nOut, FskFixedPoint2D *vOut ) { FskFixed xIn, xOut, yIn, yOut; /* Coordinates of entry and exit points */ FskFract tOut1, tIn2, tOut2; /* Parameter values of same */ FskFract tInX, tOutX, tInY, tOutY; /* Parameter values for intersections */ FskFixed deltaX, deltaY; /* Direction of edge */ FskFixed xMax, xMin, yMin, yMax; /* Rectangular clipping boundaries */ register SInt32 i; UInt32 nOutCount; nOutCount = 0; /* We need to assure that the first point is duplicated as the last. */ vIn[nIn] = vIn[0]; /* Structure assignment */ /* Initialize fixed-point clip values */ xMin = (clip->x << 16) - (1 << 15); /* from 0.5 to N-0.5 */ yMin = (clip->y << 16) - (1 << 15); xMax = xMin + ((clip->width ) << 16); yMax = yMin + ((clip->height) << 16); for (i = nIn; i-- > 0; vIn++) { /* Edge V[i]V[i+1] */ /* Determine X direction of edge */ if (((deltaX = (vIn + 1)->x - vIn->x) > 0) || ((deltaX == 0) && (vIn->x > xMax)) ) { xIn = xMin; xOut = xMax; } /* l[i] points right */ else { xIn = xMax; xOut = xMin; } /* l[i] points left */ if (deltaX != 0) tOutX = SafeTDivide(xOut - vIn->x, deltaX); else if ((vIn->x <= xMax) && (xMin <= vIn->x)) tOutX = POSITIVE_INFINITY; else tOutX = NEGATIVE_INFINITY; /* Determine Y direction of edge */ if (((deltaY = (vIn + 1)->y - vIn->y) > 0) || ((deltaY == 0) && (vIn->y > yMax)) ) { yIn = yMin; yOut = yMax; } /* l[i] points up */ else { yIn = yMax; yOut = yMin; } /* l[i] points down */ if (deltaY != 0) tOutY = SafeTDivide(yOut - vIn->y, deltaY); else if ((vIn->y <= yMax) && (yMin <= vIn->y)) tOutY = POSITIVE_INFINITY; else tOutY = NEGATIVE_INFINITY; /* Order the two exit points */ if (tOutX < tOutY) { tOut1 = tOutX; tOut2 = tOutY; } /* First exit at x, then y */ else { tOut1 = tOutY; tOut2 = tOutX; } /* First exit at y, then x */ if (tOut2 > 0) { /* There could be output -- compute tIn2 */ if (deltaX != 0) tInX = SafeTDivide(xIn - vIn->x, deltaX); else tInX = NEGATIVE_INFINITY; if (deltaY != 0) tInY = SafeTDivide(yIn - vIn->y, deltaY); else tInY = NEGATIVE_INFINITY; if (tInX < tInY) tIn2 = tInY; else tIn2 = tInX; if (tOut1 < tIn2) { /* No visible segment */ if ((0 < tOut1) && (tOut1 <= T_ONE)) { /* Line crosses over intermediate corner region */ if (tInX < tInY) AppendVertex(xOut, yIn); else AppendVertex(xIn, yOut); } } else { /* Line crosses through window */ if ((0 < tOut1) && (tIn2 <= T_ONE)) { if (0 < tIn2) { /* Visible segment */ if (tInX > tInY) AppendVertex(xIn, vIn->y + FskFixedNMul(tInX, deltaY, T_BITS)); else AppendVertex(vIn->x + FskFixedNMul(tInY, deltaX, T_BITS), yIn); } if (T_ONE > tOut1) { if (tOutX < tOutY) AppendVertex(xOut, vIn->y + FskFixedNMul(tOutX, deltaY, T_BITS)); else AppendVertex(vIn->x + FskFixedNMul(tOutY, deltaX, T_BITS), yOut); } else AppendVertex((vIn + 1)->x, (vIn + 1)->y); } } if ((0 < tOut2) && (tOut2 <= T_ONE)) AppendVertex(xOut, yOut); } } *nOut = nOutCount; }
MStatus CXRayObjectExport::ExportPart(CEditableObject* O, MDagPath& mdagPath, MObject& mComponent) { MStatus stat = MS::kSuccess; MSpace::Space space = MSpace::kWorld; MFnMesh fnMesh( mdagPath, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MFnMesh initialization.\n"); return MS::kFailure; } MString mdagPathNodeName = fnMesh.name(); MFnDagNode dagNode1(mdagPath); u32 pc = dagNode1.parentCount(); for(u32 ip=0;ip<pc;++ip) { MObject object_parent = dagNode1.parent(ip, &stat); if(object_parent.hasFn(MFn::kTransform)) { MFnTransform parent_transform(object_parent,&stat); if ( MS::kSuccess == stat) { mdagPathNodeName = parent_transform.name(); break; } } } MItMeshPolygon meshPoly( mdagPath, mComponent, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MItMeshPolygon initialization.\n"); return MS::kFailure; } MItMeshVertex vtxIter( mdagPath, mComponent, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MItMeshVertex initialization.\n"); return MS::kFailure; } // If the shape is instanced then we need to determine which // instance this path refers to. // int instanceNum = 0; if (mdagPath.isInstanced()) instanceNum = mdagPath.instanceNumber(); // Get a list of all shaders attached to this mesh MObjectArray rgShaders; MIntArray texMap; MStatus status; status = fnMesh.getConnectedShaders (instanceNum, rgShaders, texMap); if (status == MStatus::kFailure) { Log("! Unable to load shaders for mesh"); return (MStatus::kFailure); } XRShaderDataVec xr_data; { for ( int i=0; i<(int)rgShaders.length(); i++ ) { MObject shader = rgShaders[i]; xr_data.push_back(SXRShaderData()); SXRShaderData& D = xr_data.back(); status = parseShader(shader, D); if (status == MStatus::kFailure) { status.perror ("Unable to retrieve filename of texture"); continue; } } } CEditableMesh* MESH = new CEditableMesh(O); MESH->SetName(mdagPathNodeName.asChar()); O->AppendMesh(MESH); int objectIdx, length; // Find i such that objectGroupsTablePtr[i] corresponds to the // object node pointed to by mdagPath length = objectNodeNamesArray.length(); { for( int i=0; i<length; i++ ) { if( objectNodeNamesArray[i] == mdagPathNodeName ) { objectIdx = i; break; } } } // Reserve uv table { VMapVec& _vmaps = MESH->m_VMaps; _vmaps.resize (1); st_VMap*& VM = _vmaps.back(); VM = new st_VMap("Texture",vmtUV,false); } // write faces { using FaceVec = xr_vector<st_Face>; using FaceIt = FaceVec::iterator; VMapVec& _vmaps = MESH->m_VMaps; SurfFaces& _surf_faces = MESH->m_SurfFaces; VMRefsVec& _vmrefs = MESH->m_VMRefs; // temp variables FvectorVec _points; FaceVec _faces; U32Vec _sgs; int f_cnt = fnMesh.numPolygons(); _sgs.reserve (f_cnt); _faces.reserve (f_cnt); _vmrefs.reserve (f_cnt*3); // int lastSmoothingGroup = INITIALIZE_SMOOTHING; MPointArray rgpt; MIntArray rgint; PtLookupMap ptMap; CSurface* surf = 0; for ( ; !meshPoly.isDone(); meshPoly.next()){ // Write out the smoothing group that this polygon belongs to // We only write out the smoothing group if it is different // from the last polygon. // int compIdx = meshPoly.index(); int smoothingGroup = polySmoothingGroups[ compIdx ]; // for each polygon, first setup the reverse mapping // between object-relative vertex indices and face-relative // vertex indices ptMap.clear(); for (int i=0; i<(int)meshPoly.polygonVertexCount(); i++) ptMap.insert (PtLookupMap::value_type(meshPoly.vertexIndex(i), i) ); // verify polygon zero area if (meshPoly.zeroArea()){ status = MS::kFailure; Log("! polygon have zero area:",meshPoly.index()); return status; } // verify polygon zero UV area /* if (meshPoly.zeroUVArea()){ status = MS::kFailure; Log("! polygon have zero UV area:",meshPoly.index()); return status; } */ // verify polygon has UV information if (!meshPoly.hasUVs (&status)) { status = MS::kFailure; Log("! polygon is missing UV information:",meshPoly.index()); return status; } int cTri; // now iterate through each triangle on this polygon and create a triangle object in our list status = meshPoly.numTriangles (cTri); if (!status) { Log("! can't getting triangle count"); return status; } for (int i=0; i < cTri; i++) { // for each triangle, first get the triangle data rgpt.clear();//triangle vertices rgint.clear();//triangle vertex indices // triangles that come from object are retrieved in world space status = meshPoly.getTriangle (i, rgpt, rgint, MSpace::kWorld); if (!status) { Log("! can't getting triangle for mesh poly"); return status; } if ((rgpt.length() != 3) || (rgint.length() != 3)) { Msg("! 3 points not returned for triangle"); return MS::kFailure; } // Write out vertex/uv index information // R_ASSERT2(fnMesh.numUVs()>0,"Can't find uvmaps."); _faces.push_back(st_Face()); _sgs.push_back(smoothingGroup); //set_smooth set_smoth_flags( _sgs.back(), rgint ); st_Face& f_it = _faces.back(); for ( int vtx=0; vtx<3; vtx++ ) { // get face-relative vertex PtLookupMap::iterator mapIt; int vtLocal, vtUV; int vt = rgint[vtx]; mapIt = ptMap.find(vt); Fvector2 uv; if (mapIt == ptMap.end()){ Msg("! Can't find local index."); return MS::kFailure; } vtLocal = (*mapIt).second; status = meshPoly.getUVIndex (vtLocal, vtUV, uv.x, uv.y); if (!status) { Msg("! error getting UV Index for local vertex '%d' and object vertex '%d'",vtLocal,vt); return status; } // flip v-part uv.y=1.f-uv.y; f_it.pv[2-vtx].pindex = AppendVertex(_points,rgpt[vtx]); f_it.pv[2-vtx].vmref = _vmrefs.size(); _vmrefs.push_back (st_VMapPtLst()); st_VMapPtLst& vm_lst = _vmrefs.back(); vm_lst.count = 1; vm_lst.pts = xr_alloc<st_VMapPt>(vm_lst.count); vm_lst.pts[0].vmap_index= 0; vm_lst.pts[0].index = AppendUV(_vmaps.back(),uv); } // out face material int iTexture = texMap[meshPoly.index()]; if (iTexture<0) xrDebug::Fatal(DEBUG_INFO,"Can't find material for polygon: %d",meshPoly.index()); SXRShaderData& D= xr_data[iTexture]; int compIdx = meshPoly.index(); surf = MESH->Parent()->CreateSurface(getMaterialName(mdagPath, compIdx, objectIdx),D); if (!surf) return MStatus::kFailure; _surf_faces[surf].push_back(_faces.size()-1); } } { // copy from temp MESH->m_VertCount = _points.size(); MESH->m_FaceCount = _faces.size(); MESH->m_Vertices = xr_alloc<Fvector>(MESH->m_VertCount); Memory.mem_copy (MESH->m_Vertices,&*_points.begin(),MESH->m_VertCount*sizeof(Fvector)); MESH->m_Faces = xr_alloc<st_Face>(MESH->m_FaceCount); Memory.mem_copy (MESH->m_Faces,&*_faces.begin(),MESH->m_FaceCount*sizeof(st_Face)); MESH->m_SmoothGroups = xr_alloc<u32>(MESH->m_FaceCount); Memory.mem_copy (MESH->m_SmoothGroups,&*_sgs.begin(),MESH->m_FaceCount*sizeof(u32)); MESH->RecomputeBBox (); } if ((MESH->GetVertexCount()<4)||(MESH->GetFaceCount()<2)) { Log ("! Invalid mesh: '%s'. Faces<2 or Verts<4",*MESH->Name()); return MS::kFailure; } } return stat; }