コード例 #1
0
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;
}
コード例 #2
0
ファイル: MayaExport.cpp プロジェクト: 2asoft/xray
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;
}