public static CopyAndTransformVert VertexTransformationByMat4(Mat4 mat) { return new CopyAndTransformVert( (Vec3 basis, out Vec3 result) => { result = mat.TransformVec3(basis, 1.0); }); }
public static CopyAndTransformVInfo BMDVInfoTransformationByMat4(Mat4 mat) { return new CopyAndTransformVInfo( (VInfo basis, out VInfo result) => { BMDVInfo bmd = basis as BMDVInfo; if (bmd == null) throw new Exception("Can't treat some random VInfo as though it were a BMDVInfo when it isn't!"); result = new BMDVInfo { material = bmd.material, uv = bmd.uv, normal = Vec3.Normalize(mat.TransformVec3(bmd.normal, 0.0)) }; }); }
public List<BasicModelVert> GetBMVList(BasicModelData model, Mat4 xform) { List<BasicModelVert> list = new List<BasicModelVert>(); foreach (CutTriangle tri in cutTriangles) { List<WorkingVertex> triVerts = tri.GetCutTriangleVerts(); foreach(WorkingVertex vert in triVerts) list.Add(CSG.WorkingVertexToBMV(vert.position.xyz, vert.vinfo, model, xform, this)); } return list; }
public static CSGModel ModelFromBMD(BasicModelData input, Mat4 xform) { List<Vec3> verts = new List<Vec3>(); List<VInfo> vinfos = new List<VInfo>(); CopyAndTransformVert vx = VertexTransformationByMat4(xform); CopyAndTransformVInfo vi = BMDVInfoTransformationByMat4(xform); for (int i = 0; i < input.a_vert.Length; i++) { TransformAndAddVec3(verts, new Vec3 { x = input.x[input.a_vert[i]], y = input.y[input.a_vert[i]], z = input.z[input.a_vert[i]] }, vx); TransformAndAddVec3(verts, new Vec3 { x = input.x[input.b_vert[i]], y = input.y[input.b_vert[i]], z = input.z[input.b_vert[i]] }, vx); TransformAndAddVec3(verts, new Vec3 { x = input.x[input.c_vert[i]], y = input.y[input.c_vert[i]], z = input.z[input.c_vert[i]] }, vx); TransformAndAddVInfo(vinfos, new BMDVInfo { material = nextMaterial, uv = new Vec2 { x = input.u[input.a_uv[i]], y = input.v[input.a_uv[i]] }, normal = new Vec3 { x = input.nx[input.a_norm[i]], y = input.ny[input.a_norm[i]], z = input.nz[input.a_norm[i]] } }, vi); TransformAndAddVInfo(vinfos, new BMDVInfo { material = nextMaterial, uv = new Vec2 { x = input.u[input.b_uv[i]], y = input.v[input.b_uv[i]] }, normal = new Vec3 { x = input.nx[input.b_norm[i]], y = input.ny[input.b_norm[i]], z = input.nz[input.b_norm[i]] } }, vi); TransformAndAddVInfo(vinfos, new BMDVInfo { material = nextMaterial, uv = new Vec2 { x = input.u[input.c_uv[i]], y = input.v[input.c_uv[i]] }, normal = new Vec3 { x = input.nx[input.c_norm[i]], y = input.ny[input.c_norm[i]], z = input.nz[input.c_norm[i]] } }, vi); } nextMaterial++; return new CSGModel(verts, vinfos); }
// Makes a ModelInput object from a BasicModelData object (with verts and normals transformed by the 4x4 xform matrix) public static ModelInput FromBasicModelData(BasicModelData data, Mat4 xform) { List<Vec3> verts = new List<Vec3>(); List<int> vertMapping = new List<int>(); for (int i = 0; i < data.x.Length; i++) { Vec3 vert = xform.TransformVec3(new Vec3 { x = data.x[i], y = data.y[i], z = data.z[i] }, 1.0); int index = verts.FindIndex(vec => vec.x == vert.x && vec.y == vert.y && vec.z == vert.z); if (index == -1) { vertMapping.Add(verts.Count); verts.Add(vert); } else vertMapping.Add(index); } int[][] t_v_indices = new int[data.a_vert.Length][]; for (int i = 0; i < data.a_vert.Length; i++) { int a = vertMapping[(int)data.a_vert[i]]; int b = vertMapping[(int)data.b_vert[i]]; int c = vertMapping[(int)data.c_vert[i]]; t_v_indices[i] = new int[] { a, b, c }; } return new ModelInput(verts.ToArray(), t_v_indices); }
// Creates a rotation around a point // TODO: check whether this actually works or not !!! public static Mat4 RotationAroundPoint(Mat3 rot, Vec3 point) { Mat3 ident = Mat3.Identity; return(Mat4.FromPositionAndOrientation((rot * point), ident) * Mat4.FromMat3(rot) * Mat4.FromPositionAndOrientation(-(point), ident)); }
// Function that transforms stuff and does interpolation for vertices that were created in the middles of faces // TODO: replace with a generic user-vertex-info function public static BasicModelVert WorkingVertexToBMV(Vec3 position, VInfoReference[] vinfos, BasicModelData input_model, Mat4 input_xform, WorkingModel working_model) { Vec3 normal = Vec3.Zero; Vec2 uv = Vec2.Zero; foreach (VInfoReference vinfo in vinfos) { int index = vinfo.index; if (index != -1) { int tri = index / 3; int vert = index % 3; double weight = vinfo.weight; int normal_index = (int)(vert == 0 ? input_model.a_norm[tri] : vert == 1 ? input_model.b_norm[tri] : input_model.c_norm[tri]); normal += weight * input_xform.TransformVec3(new Vec3 { x = input_model.nx[normal_index], y = input_model.ny[normal_index], z = input_model.nz[normal_index] }, 0.0); int uv_index = (int)(vert == 0 ? input_model.a_uv[tri] : vert == 1 ? input_model.b_uv[tri] : input_model.c_uv[tri]); uv += weight * new Vec2 { x = input_model.u[uv_index], y = input_model.v[uv_index] }; } } return new BasicModelVert { position = position, normal = Vec3.Normalize(normal), uv = uv }; }