//读出CVector3数组 public static uint fread(ref CVector3[] buffer, uint length, FileStream f) { uint l = 0; try { for (uint i = 0; i < length / 12; i++) { buffer[i] = new CVector3(); Byte[] bts = new Byte[4]; l += (uint)f.Read(bts, 0, 4); buffer[i].x = FileHead.byte2float(bts); l += (uint)f.Read(bts, 0, 4); buffer[i].y = FileHead.byte2float(bts); l += (uint)f.Read(bts, 0, 4); buffer[i].z = FileHead.byte2float(bts); } return(l); } catch (Exception ex) { Debug.WriteLine(f.Name + " 读取出错"); Debug.WriteLine(ex.ToString()); return(l); } }
//返回两个矢量的叉积 CVector3 Cross(CVector3 p1, CVector3 p2) { CVector3 c = new CVector3(); c.x = ((p1.y * p2.z) - (p1.z * p2.y)); c.y = ((p1.z * p2.x) - (p1.x * p2.z)); c.z = ((p1.x * p2.y) - (p1.y * p2.x)); return(c); }
//返回矢量的缩放 CVector3 DivideVectorByScaler(CVector3 v, float Scaler) { CVector3 vr = new CVector3(); vr.x = v.x / Scaler; vr.y = v.y / Scaler; vr.z = v.z / Scaler; return(vr); }
//返回两个矢量的和 CVector3 AddVector(CVector3 p1, CVector3 p2) { CVector3 v = new CVector3(); v.x = p1.x + p2.x; v.y = p1.y + p2.y; v.z = p1.z + p2.z; return(v); }
//求两点决定的矢量 CVector3 Vector(CVector3 p1, CVector3 p2) { CVector3 v = new CVector3(); v.x = p1.x - p2.x; v.y = p1.y - p2.y; v.z = p1.z - p2.z; return(v); }
//规范化矢量 CVector3 Normalize(CVector3 v) { CVector3 n = new CVector3(); double mag = Mag(v); n.x = v.x / (float)mag; n.y = v.y / (float)mag; n.z = v.z / (float)mag; return(n); }
//模型单位归一化 protected void LoadBox() { boxMax = new CVector3(); boxMin = new CVector3(); boxMax.x = float.MinValue; boxMax.y = float.MinValue; boxMax.z = float.MinValue; boxMin.x = float.MaxValue; boxMin.y = float.MaxValue; boxMin.z = float.MaxValue; //获取模型的边界值 for (int i = 0; i < model.numOfObjects; i++) { t3DObject pObject = model.pObject[i]; for (int j = 0; j < pObject.numOfVerts; j++) { float x = pObject.pVerts[j].x / 1000; float y = pObject.pVerts[j].y / 1000; float z = pObject.pVerts[j].z / 1000; if (boxMin.x > x) { boxMin.x = x; } if (boxMin.y > y) { boxMin.y = y; } if (boxMin.z > z) { boxMin.z = z; } if (boxMax.x < x) { boxMax.x = x; } if (boxMax.y < y) { boxMax.y = y; } if (boxMax.z < z) { boxMax.z = z; } } } //计算模型的宽度、高度和深度 w = (boxMax.x - boxMin.x); // OutputAbs(boxMax.x) + OutputAbs(boxMin.x); h = (boxMax.y - boxMin.y); // OutputAbs(boxMax.y) + OutputAbs(boxMin.y); d = (boxMax.z - boxMin.z); // OutputAbs(boxMax.z) + OutputAbs(boxMin.z); //计算模型的中心 cx = (boxMax.x + boxMin.x) / 2.0; cy = (boxMax.y + boxMin.y) / 2.0; cz = (boxMax.z + boxMin.z) / 2.0; //计算归一化所需的缩放比例 scale = OutputMax(OutputMax(w, h), d); scale = 4.0f / scale;//根据模型实际来决定 //导入模型的单位为mm,将单位转换为m for (int i = 0; i < model.numOfObjects; i++) { t3DObject pObject = model.pObject[i]; for (int j = 0; j < pObject.numOfVerts; j++) { pObject.pVerts[j].x /= 1000; pObject.pVerts[j].y /= 1000; pObject.pVerts[j].z /= 1000; //pObject.pVerts[j].x -= (float)cx; //pObject.pVerts[j].y -= (float)cy; //pObject.pVerts[j].z -= (float)cz; } } }
//矢量的模 double Mag(CVector3 v) { return(Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z)); }
//下面的这些函数主要用来计算顶点的法向量,顶点的法向量主要用来计算光照 //计算对象的法向量 private void ComputeNormals(t3DModel pModel) { CVector3 vVector1, vVector2, vNormal; CVector3[] vPoly; vPoly = new CVector3[3]; //如果模型中没有对象,则返回 if (pModel.numOfObjects <= 0) { return; } //遍历模型中所有的对象 for (int index = 0; index < pModel.numOfObjects; index++) { //获得当前对象 t3DObject pObject = pModel.pObject[index]; //分配需要的空间 CVector3[] pNormals = new CVector3[pObject.numOfFaces]; CVector3[] pTempNormals = new CVector3[pObject.numOfFaces]; pObject.pNormals = new CVector3[pObject.numOfVerts]; //遍历对象所有面 for (int i = 0; i < pObject.numOfFaces; i++) { vPoly[0] = pObject.pVerts[pObject.pFaces[i].vertIndex[0]]; vPoly[1] = pObject.pVerts[pObject.pFaces[i].vertIndex[1]]; vPoly[2] = pObject.pVerts[pObject.pFaces[i].vertIndex[2]]; //计算面的法向量 vVector1 = Vector(vPoly[0], vPoly[2]); vVector2 = Vector(vPoly[2], vPoly[1]); vNormal = Cross(vVector1, vVector2); pTempNormals[i] = vNormal; vNormal = Normalize(vNormal); pNormals[i] = vNormal; } //下面求顶点的法向量:顶点法向量是以该点为顶点的所有三角形法向量之和 CVector3 vSum = new CVector3(); vSum.x = 0; vSum.y = 0; vSum.z = 0; int shared = 0; //遍历所有的顶点 for (int i = 0; i < pObject.numOfVerts; i++) { for (int j = 0; j < pObject.numOfFaces; j++) { if (pObject.pFaces[j].vertIndex[0] == i || pObject.pFaces[j].vertIndex[1] == i || pObject.pFaces[j].vertIndex[2] == i) { vSum = AddVector(vSum, pTempNormals[j]); shared++; } } pObject.pNormals[i] = DivideVectorByScaler(vSum, (float)(-1 * shared)); //规范化最后的顶点法向量 pObject.pNormals[i] = Normalize(pObject.pNormals[i]); vSum.x = 0; vSum.y = 0; vSum.z = 0; shared = 0; } } }