⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvshapes.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			// Set up an array to remember where each point of each face came from
			int *pSource = new int[face_data_size];		   // very conservative
			int iSource = 0;	// running index

			// Set up a table that goes coord num => face num
			int *pCoordToFace = new int[pNode->coordIndex.num];

			// j is first index into coordIndex for each face
			for(j = 0; j< pNode->coordIndex.num; j++, iface++)
			{
				// do a face
				int nVerts = VertCount(pNode->coordIndex, j);	 // # verts in -this face-

				GxVec3f n;
	
				// note that the sense of normals depend upon ccw or cw
				// if the norms point in to the front surface no shading will be done
				// on -either side-
				// Notice the back norm, if kept, is right after the front norm
				if(pNormals->IsPerFace())
				{
					pNormals->GetFaceNormal( iface,  n );
					if(faceNorms[iface] == -1)
					{
						n = -n;
						faceNorms[iface] = numN;
						if(boolBackCull && boolCCW) n = -n;
						#if (defined(FLIP_D3D_NORMALS) && defined(CH_USE_D3D))
						n = -n;
						#endif
						pN[numN++] = n;
						if(!boolBackCull) pN[numN++] = -n;
					}
				}

				for(int k = 0; k < nVerts; k++)
				{
					pCoordToFace[j+k] = iface;	   // Build table for later
				}

				bool boolConvex = IsConvex( j, nVerts );
				int	iNumFacets = 1;				// How many individual convex facets in this face

				ChTriangulator tri;

				//boolConvex = true;  // VSP : temporary fix for this release

				if(!boolConvex)
				{
					#if 1
					if(tri.Attach(pNode->coordIndex.values + j, (GxVec3f*)(pC3->point.values), nVerts))
					{
						iNumFacets = tri.GetCount();
					}
					else
					{
						boolConvex = true;	// triangulation failed. Proceed as if convex
					}
					#endif
				}

				for( int iFacet	= 0; iFacet < iNumFacets; iFacet++)
				{
					int nVertsFacet = boolConvex ? nVerts : 3;
					face_data[ifd] = nVertsFacet;
					if(!boolBackCull) face_data[ifd+2*nVertsFacet+1] = nVertsFacet;
					ifd++;

					int	triIndex[3];

					if(!boolConvex)
					{
						tri.GetTriangle(iFacet, triIndex);
					}
					for(int k = 0; k < nVertsFacet; k++)
					{
						int normIndex;
						int vertIndex;
						int iVertNumber;
						if(boolConvex)
						{
							iVertNumber = j + k;
						}
						else
						{
							iVertNumber = j + triIndex[k];
						}
						int index = pNode->coordIndex.values[iVertNumber];
					
						// First, add a vert to the vert array, and remember where in pV it is
						// To save even more space, we could build a tree where the key is index + texIndex
						// But that would be slower, probably.
						if(boolUseTexture) 
						{
							int texIndex = pTxMap->GetIndex(iVertNumber);
							vertIndex = -1;
							if(verts[index] == -1)
							{
								// Store the first occurrence of a unique vertex into pV, and save where
								// pV will store all the -used- vertices from the C3 node
								// Also save the tex index, so we can see on later verts if their
								// tex coords match. If so, we'll be able to reuse this vertex.
								// This enforces the rule: Different tex coords ==> different verts
								int iC3 = index * 3;
								GxVec3f p;
								p.x() = pC3->point.values[iC3];
								p.y() = pC3->point.values[iC3+1];
								p.z() = pC3->point.values[iC3+2];
								verts[index] = numV;
								vertIndex = numV;
								pV[numV++] = p;
								texIndices[index] = texIndex;
							}
							else if(texIndices[index] == texIndex)
							{
								vertIndex = verts[index];	// tex coords match, use the shared array
							}
							else
							{
								int iC3 = index * 3;	  // Use the unshared array
								GxVec3f p;
								p.x() = pC3->point.values[iC3];
								p.y() = pC3->point.values[iC3+1];
								p.z() = pC3->point.values[iC3+2];
								texVerts[iVertNumber] = numV;
								vertIndex = numV;
								pV[numV++] = p;
							}

						}
						else
						{
							if(verts[index] == -1)
							{
								// Store the first occurrence of a unique vertex into pV, and save where
								// pV will store all the -used- vertices from the C3 node
								int iC3 = index * 3;
								GxVec3f p;
								p.x() = pC3->point.values[iC3];
								p.y() = pC3->point.values[iC3+1];
								p.z() = pC3->point.values[iC3+2];
								verts[index] = numV;
								vertIndex = numV;
								pV[numV++] = p;
							}
							else
							{
								vertIndex = verts[index];
							}
						
						}
						// Get the normal, if it's by vertex or default ....
						// We store it in one of three arrays, and remember its index
						// in the pN array
						if(pNormals->IsPerFace())
						{
							normIndex = faceNorms[iface];
						}
						else if(pNormals->IsPerVertex())
						{	
							// This could be better if we saved 
							// by normal index instead of vertNumber					
							pNormals->GetVertexNormal( iVertNumber,  n );
							n = -n;
							if(uniqueNorms[iVertNumber] == -1)
							{
								uniqueNorms[iVertNumber] = numN;
								//	n.z() = -n.z();

								if(boolBackCull && boolCCW) n = -n;
								#if (defined(FLIP_D3D_NORMALS) && defined(CH_USE_D3D))
								n = -n;
								#endif
								pN[numN++] = n;
								if(!boolBackCull) pN[numN++] = -n;
							}
							normIndex = uniqueNorms[iVertNumber];
						}
						else
						{
							chuint32 normFlag;
							pNormals->GetDefaultNormal( iVertNumber, iface,  n, normFlag );
							n = -n;
							#if (defined(FLIP_D3D_NORMALS) && defined(CH_USE_D3D))
							n = -n;
							#endif
							if(normFlag & GX_NORMAL_FACE)
							{
								if(faceNorms[iface] == -1)
								{
									faceNorms[iface] = numN;
									if(boolBackCull && boolCCW) n = -n;
									pN[numN++] = n;
									if(!boolBackCull) pN[numN++] = -n;
								}
								normIndex = faceNorms[iface];
							}
							else if(normFlag & GX_NORMAL_ALL_FACES)
							{
								if(sharedNorms[index] == -1)
								{
									sharedNorms[index] = numN;
									if(boolBackCull && boolCCW) n = -n;
									#if (defined(FLIP_D3D_NORMALS) && defined(CH_USE_D3D))
									n = -n;
									#endif
									pN[numN++] = n;
									if(!boolBackCull) pN[numN++] = -n;
								}
								normIndex = sharedNorms[index];
							}
							else
							{
								if(uniqueNorms[iVertNumber] == -1)
								{
									uniqueNorms[iVertNumber] = numN;
									if(boolBackCull && boolCCW) n = -n;
									#if (defined(FLIP_D3D_NORMALS) && defined(CH_USE_D3D))
									n = -n;
									#endif
									pN[numN++] = n;
									if(!boolBackCull) pN[numN++] = -n;
								}
								normIndex = uniqueNorms[iVertNumber];
							}
						}

						// Whew, now we have indices for both vert and norm, so add them to 
						// the face_data

						int bump = 0;
						if(!boolBackCull || !boolCCW)
						{
							face_data[ifd+k*2] = vertIndex;
							face_data[ifd+k*2+1] = normIndex++;
							bump = 2 * nVertsFacet + 1;
							pSource[iSource+k] = iVertNumber;
						}

						// Add backface index
						if(!boolBackCull || boolCCW)
						{
							int reverseIndex = ifd + 2 * nVertsFacet - 2 * k - 2 + bump;
							face_data[reverseIndex] = vertIndex;
							face_data[reverseIndex + 1] = normIndex;
							pSource[iSource + nVertsFacet - k - 1 + (bump?nVertsFacet:0)] = iVertNumber;
						}

					
					}
					ifd += nVertsFacet * 2;
					iSource += nVertsFacet;
					if (!boolBackCull)
					{
						ifd += nVertsFacet * 2 + 1;
						iSource += nVertsFacet;
					}
				}
				j += nVerts;   	 // next face  -- the j++ in loop bumps over -1
			}


			face_data[ifd] = 0;

			// Load the verts and faces
			ChNrFaceArray facesAdded;
			int numFacesAdded;
			ChNrMeshAddFaces(mesh,
					       numV,
					       (ChNrVector*) pV,
					       numN,
					       (ChNrVector*) pN,
					       face_data,
					       &numFacesAdded,
					       &facesAdded);
		
			// Assign colors and textures to faces
			int inc = 1;
			if(!boolBackCull) inc *= 2;	 // only every other face if we did back faces
 			unsigned int ifacet;

			#if defined(CH_USE_D3D)
			numFacesAdded = facesAdded->GetSize();
			#endif

			for( ifacet = 0, j = 0; int(ifacet) < numFacesAdded; ifacet += inc)
			{
				ChNrFace elt;
				int count = ChNrFaceGetVertexCount(GetElement(facesAdded, ifacet, elt));
				D3DRelease(elt);

				for(int k = 0; k < count; k++)
				{				
 					iSource = j * inc + k;
					if(boolCCW && boolBackCull)
					{
						// reverse the texture && material coords; we already reversed the vertex order
						//iSource = j + count - k - 1; 
					}
					int	iVertNumber = pSource[iSource];
					int iface = pCoordToFace[iVertNumber];

					int index = ChNrFaceGetVertexIndex(GetElement(facesAdded,ifacet, elt), k);
					D3DRelease(elt);

					if(boolUseTexture) 
					{
						int iC3 = pNode->coordIndex.values[iVertNumber] * 3;
						GxVec3f textCoord = pTxMap->GetCoord3(iVertNumber, pC3->point.values+iC3);
						ChNrMeshSetTextureCoordinates(mesh, index, textCoord.x(), textCoord.y());
					}
					if(k == 0 || !boolColorByFace)
					{
						// Color the verts if necessary, but just faces if possible
						int iVert = boolColorByFace ? -1 : index;  // -1 means set face color
						materialMap.Set(mesh, GetElement(facesAdded, unsigned(ifacet), elt), iVert, iface, iVertNumber);
						D3DRelease(elt);
					}
				}

				// If we applied a color to the face for some reason (like transparency)
				// we need to copy that color to the backface, if there is one
				// BUG HERE! We are not handling meshes with a mixture of transparency 
				// and opaque
				if( inc > 1  /*!boolBackCull && (ChNrMeshGetColorSource(mesh) == ColorFromFace )*/)
				{
					ChNrFace elt;
					ChNativeColor color = ChNrFaceGetColor(GetElement(facesAdded, ifacet, elt));
					D3DRelease(elt);
					ChNrFaceSetColor(GetElement(facesAdded, ifacet+1, elt), color);
					D3DRelease(elt);
				}

				j += count;
			}

			m_boolCanCollapse = (ChNrMeshGetColorSource(mesh) == ColorFromFace );
			//ChNrFrameSetColor(m_frame, RLCreateColorRGBA(RLVal(0.6), RLVal(0.6), RLVal(0.6),
			//	RLVal(0.4)));

			if(boolUseTexture)
			{
				// This is in case the texture is already arrived
				ChTextureHandle hdl = pTextureData->GetTextureHandle();
				if(hdl)
				{
					// Texture guy got here first, apply it
					//ChNrMeshSetTexture(mesh, hdl);
					SetTexture(pTextureData);

				}
			}  


		 	// Cleanup
			delete [] pN;
			delete [] pV;
			delete [] faceNorms;
			delete [] uniqueNorms;
			delete [] sharedNorms;
			delete [] verts;
			delete [] face_data;
			delete [] texIndices;
			delete [] texVerts;
			delete [] pSource;
			delete [] pCoordToFace;

			ChNrFree(facesAdded);							  
			delete pTxMap;

		}
		else
		{
			// Notify them of the bad node TODO
		}

		pIterator->DidAShape();
		pRC->UnlockQv();
		pRC->UnlockScene();		
	}
#endif
	return true;
}

bool ChQvIFSInstance::Draw(ChRenderContext *pRC, ChDrawIterator *pIterator)
{
#if defined( CH_USE_3DR )
	{
		G3dHandle_t hGC = pRC->GetGC();
		Dword_t  hRC = pRC->GetRC();
		QvIndexedFaceSet *pNode = (QvIndexedFaceSet *)GetNode();
		pRC->SetModelTransform(GetTransform());

		pRC->SetShading(this);

		Fixed32_t wMattNum = 0;	  // for now always use material 0
		G3dSetCurrentMatt(hGC, wMattNum );

		// Interpret shapehints; we assume there is at least one there; (we inited to make sure)
		Fixed32_t lIsCCW = (GetShapeHints()->vertexOrdering.value == QvShapeHints::COUNTERCLOCKWISE);
	    G3dSetState( hGC, G3DL_FRONT_CCW, &lIsCCW);

		// Figure out if we can backcull. solid + known order means we can
		bool boolBackCull = ((GetShapeHints()->vertexOrdering.value != QvShapeHints::UNKNOWN_ORDERING) &&
					(GetShapeHints()->shapeType.value == QvShapeHints::SOLID));
		Float_t		cull = boolBackCull;
		G3dSetMatt( hGC,  wMattNum, G3DM_BACK_CULL,	(Float_t *)&cull );
	
		// Make a material mapping; we will use later for each face
		ChQvFaceSetMaterials materialMap( this );	// making this is cheap; don't cache

		// Normals
		int	face = 0;

									/* If they can't write good nodes, don't draw them! */				 
		if(((ChQvIFSRenderData *)m_pRenderData)->IsValid())
		{
		
			ChQvIndexedFaceSetNormals *pNormals = ((ChQvIFSRenderData *)m_pRenderData)->GetNormals();


			/* Do the texture stuff - find it, make the map, set up 3dr for it, */
			int boolUseTexture = false;
	
			ChQvTextureRenderData *pTextureData = 0;
			pTextureData = (ChQvTextureRenderData*)(GetTexture2()->GetRenderData());
			if (pTextureData->GetTextureHandle()) boolUseTexture = true;
	
			ChQvIFSTextures	*pTxMap = 0;
	 
			if(boolUseTexture)
			{
				pRC->SetTexture(pTextureData->GetTextureHandle());
				pTxMap = new ChQvIFSTextures( this );	// efficient except for many-faced
															// textured ifs' with default map,
															// which are unlikely because they
															// would be b ugly, so don't
															// bother to 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -