// Call if base mesh changes public void ReStart() { mesh = MegaUtils.GetMesh(gameObject); if (mesh != null) { bbox = mesh.bounds; sverts = new Vector3[mesh.vertexCount]; verts = mesh.vertices; uvs = mesh.uv; suvs = new Vector2[mesh.uv.Length]; cols = mesh.colors; mods = GetComponents <MegaModifier>(); Array.Sort(mods, CompareOrder); for (int i = 0; i < mods.Length; i++) { if (mods[i] != null) { mods[i].ModStart(this); // Some mods like push error if we dont do this, put in error check and disable } } } UpdateMesh = -1; }
// *************************************************************************** // PS3 Code // *************************************************************************** #if true //UNITY_PS3 void Awake() { if (Application.platform == RuntimePlatform.PS3 && !Application.isEditor) { Mesh ps3mesh = MegaUtils.GetMesh(gameObject); BuildPS3Mapping(verts, ps3mesh.vertices); } }
// Set the PS3 mesh vertices from the internal modified vertex array to the new ps3 vertex array public void SetPS3Mesh() { // This is here to test the remapping works in editor mode, // remove for use as Awake() will do this. if (ps3mapping == null || ps3mapping.Length == 0) { Mesh ps3mesh = MegaUtils.GetMesh(gameObject); BuildPS3Mapping(verts, ps3mesh.vertices); } if ((dirtyChannels & MegaModChannel.Verts) != 0) { for (int i = 0; i < sverts.Length; i++) { for (int m = 0; m < ps3mapping[i].indices.Length; m++) { ps3verts[ps3mapping[i].indices[m]] = sverts[i]; } } mesh.vertices = ps3verts; } if ((dirtyChannels & MegaModChannel.UV) != 0) { mesh.uv = suvs; } if (recalcnorms) { RecalcNormals(); } if (recalcTangents) { BuildTangents(); } if (recalcbounds) { mesh.RecalculateBounds(); } if (recalcCollider) { if (meshCol == null) { meshCol = GetComponent <MeshCollider>(); } if (meshCol != null) { meshCol.sharedMesh = null; meshCol.sharedMesh = mesh; } } }
// *************************************************************************** // PS3 Code // *************************************************************************** #if true //UNITY_PS3 void Awake() { #if UNITY_5_5 || UNITY_5_6 || UNITY_2017 #else if (Application.platform == RuntimePlatform.PS3 && !Application.isEditor) { Mesh ps3mesh = MegaUtils.GetMesh(gameObject); BuildPS3Mapping(verts, ps3mesh.vertices); } #endif }
public override bool Prepare(MegaModContext mc) { if (colmesh == null) { colmesh = new MegaColliderMesh(); } if (colmesh.obj != hitObject && hitObject != null) { colmesh = new MegaColliderMesh(); // This is colldier mesh not this mesh colmesh.mesh = MegaUtils.GetMesh(hitObject); colmesh.verts = colmesh.mesh.vertices; colmesh.tris = colmesh.mesh.triangles; colmesh.normals = colmesh.mesh.normals; colmesh.obj = hitObject; } if (hitObject) { //localPos = transform.worldToLocalMatrix.MultiplyPoint(hitObject.transform.position); col = hitObject.GetComponent <Collider>(); } if (hitObject == null) { return(false); } affected.Clear(); distances.Clear(); if (offsets == null || offsets.Length != mc.mod.verts.Length) { offsets = new Vector3[mc.mod.verts.Length]; } if (normals == null || normals.Length != verts.Length) { normals = mc.mod.mesh.normals; // get current normals } if (penetration == null || penetration.Length != mc.mod.verts.Length) { penetration = new float[mc.mod.verts.Length]; } mat = Matrix4x4.identity; SetAxis(mat); return(true); }
public bool recalcBounds = true; // recalc bounds // Call this to set the source game object which has the working point cache modifier attached public void SetSource(GameObject srcobj) { if (srcobj) { if (mesh == null) { mesh = MegaUtils.GetMesh(gameObject); } Mesh srcmesh = MegaUtils.GetMesh(srcobj); if (srcmesh.vertexCount == mesh.vertexCount) { obj = srcobj; mod = (MegaPointCache)srcobj.GetComponent <MegaPointCache>(); modobj = (MegaModifyObject)srcobj.GetComponent <MegaModifyObject>(); mesh = MegaUtils.GetMesh(gameObject); } } }
public override bool Prepare(MegaModContext mc) { if (colmesh == null) { colmesh = new MegaColliderMesh(); } if (colmesh.obj != hitObject && hitObject != null) { //Debug.Log("building"); colmesh = new MegaColliderMesh(); // This is colldier mesh not this mesh colmesh.mesh = MegaUtils.GetMesh(hitObject); //Debug.Log("verts " + colmesh.mesh.vertexCount); colmesh.verts = colmesh.mesh.vertices; colmesh.tris = colmesh.mesh.triangles; colmesh.normals = colmesh.mesh.normals; //colmesh.tree = KDTree.MakeFromPoints(colmesh.verts); //colmesh.trilist = new VertTriList(colmesh.mesh); colmesh.obj = hitObject; //Debug.Log("Col info built"); } //Debug.Log("Done"); if (hitObject) { //localPos = transform.worldToLocalMatrix.MultiplyPoint(hitObject.transform.position); col = hitObject.collider; } if (hitObject == null) { return(false); } //if ( col == null ) //return false; affected.Clear(); distances.Clear(); if (offsets == null || offsets.Length != mc.mod.verts.Length) { offsets = new Vector3[mc.mod.verts.Length]; } if (normals == null || normals.Length != verts.Length) { normals = mc.mod.mesh.normals; // get current normals } if (penetration == null || penetration.Length != mc.mod.verts.Length) { penetration = new float[mc.mod.verts.Length]; } mat = Matrix4x4.identity; SetAxis(mat); return(true); }
// We only need to collision with outside masses so any mass not used 6 times, not if a shell // plus we give external links a different stiffness // should work from centre of mesh // Can easily thread this // We have spring builder in my max destruction soft body so use that public void VoxelMesh(GameObject obj, float size, bool fill) { if (obj == null) { return; } voxobj = obj; Mesh mesh = MegaUtils.GetMesh(voxobj); basemesh = mesh; int[] tris = mesh.triangles; Vector3[] verts = mesh.vertices; Vector3 meshsize = mesh.bounds.size; xs = Mathf.CeilToInt(meshsize.x / size); if (xs == 0) { xs = 1; } //Debug.Log("ys " + (meshsize.y / size).ToString("0.000")); ys = Mathf.CeilToInt(meshsize.y / size); if (ys == 0) { ys = 1; } zs = Mathf.CeilToInt(meshsize.z / size); if (zs == 0) { zs = 1; } origin.x = -((float)xs * 0.5f * size); //mesh.bounds.min + Jitter; origin.y = -((float)ys * 0.5f * size); //mesh.bounds.min + Jitter; origin.z = -((float)zs * 0.5f * size); //mesh.bounds.min + Jitter; // So first check all tris against each cell // first get bounds of tri // is it quicker to do each tri, get bounds and check those // or do each cell and check all tris, (can early out on this) // alloc array to hold cell data cells = new int[xs, ys, zs]; // Mmmm looks like a lot quicker otherway for 30 verts on a 4x4x4 we loop 4x4x4x30= 1920 // if we do tri and get bounds then a lot quicker could be as low as 30 or 2x2x2x30 = 240 Bounds box = new Bounds(); int gxs, gxe; int gys, gye; int gzs, gze; Vector3 min = Vector3.zero; Vector3 half = new Vector3(size * 0.5f, size * 0.5f, size * 0.5f); cellsize = new Vector3(size, size, size); //Debug.Log("Origin " + origin.ToString("0.000")); for (int i = 0; i < tris.Length; i += 3) { // do bounds on tri GetTriBounds(verts, tris, i, origin, out gxs, out gxe, out gys, out gye, out gzs, out gze); //Debug.Log("b[" + i + "] " + gxs + " " + gxe + " " + gys + " " + gye + " " + gzs + " " + gze); //for ( int z = 0; z < zs; z++ ) for (int z = gzs; z <= gze; z++) { min.z = origin.z + (z * size); //for ( int y = 0; y < ys; y++ ) for (int y = gys; y <= gye; y++) { min.y = origin.y + (y * size); //for ( int x = 0; x < xs; x++ ) for (int x = gxs; x <= gxe; x++) { min.x = origin.x + (x * size); box.SetMinMax(min, min + cellsize); //Debug.Log("box " + box.min.ToString("0.000")); // build box for cell if (AABB_Triangle_Intersection.TriangleBoxOverlap(verts[tris[i]], verts[tris[i + 1]], verts[tris[i + 2]], box)) { if (x < xs && y < ys && z < zs) { cells[x, y, z] = 1; } //Debug.Log("hit " + x + " " + y + " " + z); } } } } } // We should have a shell now, so now to fill line by line // can do for each axis and combine result (bit per axis) any bit means voxel, this will fill holes // Fill it, should do for each axis // could be a bug here here cant assume pen changes state in next block, so for pen down we get // the first block but we need end of contigous block if (fill) { for (int z = 0; z < zs; z++) { for (int y = 0; y < ys; y++) { int pd = 0; while (true) //x != -1 ) { // get pen down pd = GetXCell(cells, pd, y, z, xs); if (pd == -1) { break; } // get pen up int pu = GetXCell(cells, pd + 1, y, z, xs); if (pu == -1) { break; } for (int x = pd + 1; x < pu; x++) { cells[x, y, z] = 2; } pd = pu + 1; // pd is } } } } BuildLattice(); // Build bary coords BaryCoord[] barycoords = new BaryCoord[verts.Length]; for (int i = 0; i < verts.Length; i++) { Vector3 p = verts[i]; int x = (int)((p.x - origin.x) / CellSize); int y = (int)((p.y - origin.y) / CellSize); int z = (int)((p.z - origin.z) / CellSize); BaryCoord bc = new BaryCoord(); bc.p.x = (p.x - origin.x - (float)x * CellSize) / CellSize; bc.p.y = (p.y - origin.y - (float)y * CellSize) / CellSize; bc.p.z = (p.z - origin.z - (float)z * CellSize) / CellSize; for (int c = 0; c < 8; c++) { bc.m[c] = GetMassIndex(x, y, z, c); } //bc.m = FindMassIndex(p); //Debug.Log("[" + i + "] " + x + " " + y + " " + z + " " + p); barycoords[i] = bc; } // Rebuild verts test for (int i = 0; i < barycoords.Length; i++) { BaryCoord bc = barycoords[i]; Vector3 bl = Vector3.Lerp(voxmasses[bc.m[0]].p, voxmasses[bc.m[1]].p, bc.p.z); Vector3 tl = Vector3.Lerp(voxmasses[bc.m[4]].p, voxmasses[bc.m[5]].p, bc.p.z); Vector3 br = Vector3.Lerp(voxmasses[bc.m[3]].p, voxmasses[bc.m[2]].p, bc.p.z); Vector3 tr = Vector3.Lerp(voxmasses[bc.m[7]].p, voxmasses[bc.m[6]].p, bc.p.z); Vector3 l = Vector3.Lerp(bl, tl, bc.p.y); Vector3 r = Vector3.Lerp(br, tr, bc.p.y); verts[i] = Vector3.Lerp(l, r, bc.p.x); } //mesh.vertices = verts; }
// We have spring builder in my max destruction soft body so use that public void VoxelMesh(GameObject obj, float size, bool fill) { if (obj == null) { return; } voxobj = obj; Mesh mesh = MegaUtils.GetMesh(voxobj); basemesh = mesh; int[] tris = mesh.triangles; Vector3[] verts = mesh.vertices; origin = mesh.bounds.min; Vector3 meshsize = mesh.bounds.size; xs = Mathf.CeilToInt(meshsize.x / size); if (xs == 0) { xs = 1; } ys = Mathf.CeilToInt(meshsize.y / size); if (ys == 0) { ys = 1; } zs = Mathf.CeilToInt(meshsize.z / size); if (zs == 0) { zs = 1; } // So first check all tris against each cell // first get bounds of tri // is it quicker to do each tri, get bounds and check those // or do each cell and check all tris, (can early out on this) // alloc array to hold cell data cells = new int[xs, ys, zs]; // Mmmm looks like a lot quicker otherway for 30 verts on a 4x4x4 we loop 4x4x4x30= 1920 // if we do tri and get bounds then a lot quicker could be as low as 30 or 2x2x2x30 = 240 Bounds box = new Bounds(); int gxs, gxe; int gys, gye; int gzs, gze; Vector3 min = Vector3.zero; Vector3 half = new Vector3(size * 0.5f, size * 0.5f, size * 0.5f); cellsize = new Vector3(size, size, size); for (int i = 0; i < tris.Length; i += 3) { // do bounds on tri GetTriBounds(verts, tris, i, mesh.bounds, out gxs, out gxe, out gys, out gye, out gzs, out gze); for (int z = gzs; z < gze; z++) { min.z = mesh.bounds.min.z + (z * size); for (int y = gys; y < gye; y++) { min.y = mesh.bounds.min.y + (y * size); for (int x = gxs; x < gxe; x++) { min.x = mesh.bounds.min.x + (x * size); box.SetMinMax(min, min + cellsize); // build box for cell if (AABB_Triangle_Intersection.TriangleBoxOverlap(verts[tris[i]], verts[tris[i + 1]], verts[tris[i + 2]], box)) { cells[x, y, z] = 1; } } } } } // We should have a shell now, so now to fill line by line // can do for each axis and combine result (bit per axis) any bit means voxel, this will fill holes // Fill it, should do for each axis // could be a bug here here cant assume pen changes state in next block, so for pen down we get // the first block but we need end of contigous block if (fill) { for (int z = 0; z < zs; z++) { for (int y = 0; y < ys; y++) { int pd = 0; while (true) //x != -1 ) { // get pen down pd = GetXCell(cells, pd, y, z, xs); if (pd == -1) { break; } // get pen up int pu = GetXCell(cells, pd + 1, y, z, xs); if (pu == -1) { break; } for (int x = pd + 1; x < pu; x++) { cells[x, y, z] = 2; } pd = pu + 1; // pd is } } } } }