public static GameObject BuildRoom(RoomNode room, RoomStyle roomStyle) { GameObject boxObj = new GameObject(room.name); for (int i = 0; i < 6; i++) { Vector3 dir = Util.VecDenum(i); Bounds wallBounds = new Bounds(room.roomBounds.center + Vector3.Scale(room.roomBounds.extents, dir), Vector3.Scale(room.roomBounds.size, Util.LNot(dir))); int holeCount = 0; Bounds[] tempDoorSet = new Bounds[room.neighbors.Count]; foreach (RoomNode neighbor in room.neighbors) { //if(wallBounds.Intersects(neighbor.roomBounds)) if (RoomNode.CheckOverlap(wallBounds, neighbor.roomBounds, -1)) { Bounds b = RoomNode.OverlapBounds(room.roomBounds, neighbor.roomBounds); b.extents += Util.VecAbs(dir); tempDoorSet[holeCount] = b; holeCount++; } } Bounds[] doorSet = new Bounds[holeCount]; for (int k = 0; k < holeCount; k++) { doorSet[k] = tempDoorSet[k]; } Mesh wallMesh = BuildWall(wallBounds, doorSet, dir * -1); if (wallMesh != null) { TangentSolver.Solve(wallMesh); GameObject wallObj = new GameObject("Wall", typeof(MeshRenderer), typeof(MeshFilter), typeof(MeshCollider)); wallObj.GetComponent <MeshFilter>().mesh = wallMesh; wallObj.transform.parent = boxObj.transform; wallObj.transform.localPosition = Vector3.Scale(room.roomBounds.extents, dir); wallObj.renderer.material = roomStyle.materials[i]; wallObj.GetComponent <MeshCollider>().sharedMesh = wallMesh; } } return(boxObj); }
void Update() { if (Input.GetKeyDown(KeyCode.F7)) { renderers = FindObjectsOfType <SkinnedMeshRenderer>(); foreach (SkinnedMeshRenderer render in renderers) { //Console.WriteLine("SkinnedMeshRenderer: " + render.name); if (render.name.ToLower().Contains("cf_o_hair")) { NormalSolver.RecalculateNormals(render.sharedMesh, 60f); TangentSolver.Solve(render.sharedMesh); } } } else if (Input.GetKeyDown(KeyCode.F8)) { renderers = FindObjectsOfType <SkinnedMeshRenderer>(); foreach (SkinnedMeshRenderer render in renderers) { //Console.WriteLine("SkinnedMeshRenderer: " + render.name); if (render.name.ToLower().Contains("cf_o_hair")) { render.sharedMesh.RecalculateNormals(); TangentSolver.Solve(render.sharedMesh); } } } else if (Input.GetKeyDown(KeyCode.F9)) { renderers = FindObjectsOfType <SkinnedMeshRenderer>(); foreach (SkinnedMeshRenderer render in renderers) { if (render.name.ToLower().Contains("cf_o_hair")) { TangentSolver.Solve(render.sharedMesh); } } } }
public void Build() { float[,,] voxels = new float[size + 1, size + 1, size + 1]; int height; float hFactor; for (int z = 0; z < size + 1; z++) { for (int y = 0; y < size + 1; y++) { height = yi + y; hFactor = (float)(maxHeight - 2 * height) / (float)maxHeight; for (int x = 0; x < size + 1; x++) { voxels[x, y, z] = -hFactor + m_perlin.FractalNoise3D((float)(xi + x), (float)(yi + y), (float)(zi + z), 3, freq, 1.0f); } } } mesh = MarchingCubes.CreateMesh(voxels); //UV MAPPING Vector3[] vertices = mesh.vertices; Vector2[] uvs = new Vector2[mesh.vertices.Length]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = new Vector2(vertices[i].x, vertices[i].z); } mesh.uv = uvs; //NORMALS mesh.RecalculateNormals(); //TANGENTS TangentSolver.Solve(mesh); mesh.Optimize(); AssetDatabase.CreateAsset(mesh, "Assets/Resources/meshes/mesh" + xi + yi + zi + ".asset"); //GAMEOBJECT SETUP m_mesh.GetComponent <MeshFilter>().mesh = mesh; m_mesh.transform.localPosition = gPos; m_mesh.AddComponent <MeshCollider>(); }
void OnWizardCreate() { GameObject plane = new GameObject(); if (!string.IsNullOrEmpty(optionalName)) { plane.name = optionalName; } else { plane.name = "Plane"; } if (!createAtOrigin && cam) { plane.transform.position = cam.transform.position + cam.transform.forward * 5.0f; } else { plane.transform.position = Vector3.zero; } Vector2 anchorOffset; string anchorId; switch (anchor) { case AnchorPoint.TopLeft: anchorOffset = new Vector2(-width / 2.0f, length / 2.0f); anchorId = "TL"; break; case AnchorPoint.TopHalf: anchorOffset = new Vector2(0.0f, length / 2.0f); anchorId = "TH"; break; case AnchorPoint.TopRight: anchorOffset = new Vector2(width / 2.0f, length / 2.0f); anchorId = "TR"; break; case AnchorPoint.RightHalf: anchorOffset = new Vector2(width / 2.0f, 0.0f); anchorId = "RH"; break; case AnchorPoint.BottomRight: anchorOffset = new Vector2(width / 2.0f, -length / 2.0f); anchorId = "BR"; break; case AnchorPoint.BottomHalf: anchorOffset = new Vector2(0.0f, -length / 2.0f); anchorId = "BH"; break; case AnchorPoint.BottomLeft: anchorOffset = new Vector2(-width / 2.0f, -length / 2.0f); anchorId = "BL"; break; case AnchorPoint.LeftHalf: anchorOffset = new Vector2(-width / 2.0f, 0.0f); anchorId = "LH"; break; case AnchorPoint.Center: default: anchorOffset = Vector2.zero; anchorId = "C"; break; } MeshFilter meshFilter = (MeshFilter)plane.AddComponent(typeof(MeshFilter)); plane.AddComponent(typeof(MeshRenderer)); string planeAssetName = plane.name + widthSegments + "x" + lengthSegments + "W" + width + "L" + length + (orientation == Orientation.Horizontal? "H" : "V") + anchorId + ".asset"; Mesh m = (Mesh)AssetDatabase.LoadAssetAtPath("Assets/Meshes/" + planeAssetName, typeof(Mesh)); if (m == null) { m = new Mesh(); m.name = plane.name; int hCount2 = widthSegments + 1; int vCount2 = lengthSegments + 1; int numTriangles = widthSegments * lengthSegments * 6; int numVertices = hCount2 * vCount2; Vector3[] vertices = new Vector3[numVertices]; Vector2[] uvs = new Vector2[numVertices]; int[] triangles = new int[numTriangles]; int index = 0; float uvFactorX = 1.0f / widthSegments; float uvFactorY = 1.0f / lengthSegments; float scaleX = width / widthSegments; float scaleY = length / lengthSegments; for (float y = 0.0f; y < vCount2; y++) { for (float x = 0.0f; x < hCount2; x++) { if (orientation == Orientation.Horizontal) { vertices[index] = new Vector3(x * scaleX - width / 2f - anchorOffset.x, 0.0f, y * scaleY - length / 2f - anchorOffset.y); } else { vertices[index] = new Vector3(x * scaleX - width / 2f - anchorOffset.x, y * scaleY - length / 2f - anchorOffset.y, 0.0f); } uvs[index++] = new Vector2(x * uvFactorX, y * uvFactorY); } } index = 0; for (int y = 0; y < lengthSegments; y++) { for (int x = 0; x < widthSegments; x++) { triangles[index] = (y * hCount2) + x; triangles[index + 1] = ((y + 1) * hCount2) + x; triangles[index + 2] = (y * hCount2) + x + 1; triangles[index + 3] = ((y + 1) * hCount2) + x; triangles[index + 4] = ((y + 1) * hCount2) + x + 1; triangles[index + 5] = (y * hCount2) + x + 1; index += 6; } } m.vertices = vertices; m.uv = uvs; m.triangles = triangles; m.RecalculateNormals(); TangentSolver.Solve(m); AssetDatabase.CreateAsset(m, "Assets/Editor/" + planeAssetName); AssetDatabase.SaveAssets(); } meshFilter.sharedMesh = m; m.RecalculateBounds(); if (addCollider) { plane.AddComponent(typeof(BoxCollider)); } Selection.activeObject = plane; }
// Use this for initialization void Start() { TangentSolver.Solve(mesh, false); }
override protected Mesh CreateProduct(Mesh mesh = null) { // Debug.Log("create product"); NPVoxMeshOutput meshOutput = (Input as NPVoxMeshOutput); if (meshOutput && meshOutput.GetProduct() && TextureAtlas) { TextureAtlas.GetMaterial(SourceMaterial); NPVoxFaces includedFaces = GetIncludedFaces(); NPVoxToUnity npVoxToUnity = InputMeshFactory.GetNPVoxToUnity(); int faceCount = GetFaceCount(); NPVoxBox originalBox = InputMeshFactory.GetVoxModel().BoundingBox; NPVoxBox cutoutBox = originalBox.Clone(); NPVoxFaces cutout = InputMeshFactory.Cutout; Vector3 cutoutOffset = Vector3.zero; if (cutout != null) { Vector3 originalCenter = cutoutBox.SaveCenter; cutoutBox.Left = (sbyte)Mathf.Abs(cutout.Left); cutoutBox.Down = (sbyte)Mathf.Abs(cutout.Down); cutoutBox.Back = (sbyte)Mathf.Abs(cutout.Back); cutoutBox.Right = (sbyte)(cutoutBox.Right - (sbyte)Mathf.Abs(cutout.Right)); cutoutBox.Up = (sbyte)(cutoutBox.Up - (sbyte)Mathf.Abs(cutout.Up)); cutoutBox.Forward = (sbyte)(cutoutBox.Forward - (sbyte)Mathf.Abs(cutout.Forward)); cutoutOffset = Vector3.Scale(originalCenter - cutoutBox.SaveCenter, InputMeshFactory.VoxelSize); } // we have to be careful. Unlike cutout, which is already removed from the mesh we want to render, the inset is not yet applied and // also won't result in a "move" of the object. So it's important that we calculate a correct offset for our final mesh. NPVoxBox insetBox = cutoutBox.Clone(); Vector3 insetOffset = Vector3.zero; if (inset != null) { Vector3 cutoutCenter = cutoutBox.SaveCenter; insetBox.Left += (sbyte)Mathf.Abs(inset.Left); insetBox.Right -= (sbyte)Mathf.Abs(inset.Right); insetBox.Down += (sbyte)Mathf.Abs(inset.Down); insetBox.Up -= (sbyte)Mathf.Abs(inset.Up); insetBox.Back += (sbyte)Mathf.Abs(inset.Back); insetBox.Forward -= (sbyte)Mathf.Abs(inset.Forward); insetOffset = Vector3.Scale(cutoutCenter - insetBox.SaveCenter, InputMeshFactory.VoxelSize); } Vector3 insetCenter = insetBox.SaveCenter; if (Baked45Angle) { backSlot = CreateTexture(backSlot, includedFaces.Back != 0, insetBox.Size.X, insetBox.Size.Y, Quaternion.Euler(-45, 0, 0), npVoxToUnity.ToUnityPosition(new Vector3(insetCenter.x, insetCenter.y, insetBox.Back)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.X, ((float)insetBox.Size.Y) / Mathf.Sqrt(2))) * 0.5f, Quaternion.Euler(+45, 0, 0) ); downSlot = CreateTexture(downSlot, includedFaces.Down != 0, insetBox.Size.X, insetBox.Size.Z * 3, Quaternion.Euler(-45, 0, 0), npVoxToUnity.ToUnityPosition(new Vector3(insetCenter.x, insetBox.Down, insetCenter.z)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.X, ((float)insetBox.Size.Z) / Mathf.Sqrt(2))) * 0.5f, Quaternion.Euler(-45, 0, 0) ); leftSlot = CreateTexture(leftSlot, false, 0, 0, Quaternion.identity, Vector3.zero, Vector2.zero, Quaternion.identity); rightSlot = CreateTexture(rightSlot, false, 0, 0, Quaternion.identity, Vector3.zero, Vector2.zero, Quaternion.identity); upSlot = CreateTexture(upSlot, false, 0, 0, Quaternion.identity, Vector3.zero, Vector2.zero, Quaternion.identity); forwardSlot = CreateTexture(forwardSlot, false, 0, 0, Quaternion.identity, Vector3.zero, Vector2.zero, Quaternion.identity); } else { leftSlot = CreateTexture(leftSlot, includedFaces.Left != 0, insetBox.Size.Z, insetBox.Size.Y, Quaternion.Euler(0, 90, 0), npVoxToUnity.ToUnityPosition(new Vector3(insetBox.Left, insetCenter.y, insetCenter.z)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.Z, insetBox.Size.Y)) * 0.5f, Quaternion.identity ); rightSlot = CreateTexture(rightSlot, includedFaces.Right != 0, insetBox.Size.Z, insetBox.Size.Y, Quaternion.Euler(0, -90, 0), npVoxToUnity.ToUnityPosition(new Vector3(insetBox.Right, insetCenter.y, insetCenter.z)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.Z, insetBox.Size.Y)) * 0.5f, Quaternion.identity ); downSlot = CreateTexture(downSlot, includedFaces.Down != 0, insetBox.Size.X, insetBox.Size.Z, Quaternion.Euler(-90, 0, 0), npVoxToUnity.ToUnityPosition(new Vector3(insetCenter.x, insetBox.Down, insetCenter.z)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.X, insetBox.Size.Z)) * 0.5f, Quaternion.identity ); upSlot = CreateTexture(upSlot, includedFaces.Up != 0, insetBox.Size.X, insetBox.Size.Z, Quaternion.Euler(90, 0, 180), npVoxToUnity.ToUnityPosition(new Vector3(insetCenter.x, insetBox.Up, insetCenter.z)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.X, insetBox.Size.Z)) * 0.5f, Quaternion.identity ); backSlot = CreateTexture(backSlot, includedFaces.Back != 0, insetBox.Size.X, insetBox.Size.Y, Quaternion.Euler(0, 0, 0), npVoxToUnity.ToUnityPosition(new Vector3(insetCenter.x, insetCenter.y, insetBox.Back)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.X, insetBox.Size.Y)) * 0.5f, Quaternion.identity ); forwardSlot = CreateTexture(forwardSlot, includedFaces.Forward != 0, insetBox.Size.X, insetBox.Size.Y, Quaternion.Euler(-180, 0, 0), npVoxToUnity.ToUnityPosition(new Vector3(insetCenter.x, insetCenter.y, insetBox.Forward)), npVoxToUnity.ToUnityDirection(new Vector2(insetBox.Size.X, insetBox.Size.Y)) * 0.5f, Quaternion.identity ); } slotsAllocatedAtTA = TextureAtlas; if (mesh == null) { mesh = new Mesh(); } else { mesh.Clear(); } mesh.name = "zzz Cube Simplifier Mesh"; int border = 1; var vertices = new Vector3[faceCount * 4]; var uvs = new Vector2[faceCount * 4]; var tris = new int[faceCount * 3 * 2]; var normals = new Vector3[faceCount * 4]; int v = 0; int t = 0; int v0 = 0; System.Action <Vector3, NPVoxTextureAtlas.Slot> addQuad = (Vector3 dir, NPVoxTextureAtlas.Slot theSlot) => { normals[v0] = dir; normals[v0 + 1] = dir; normals[v0 + 2] = dir; normals[v0 + 3] = dir; tris[t++] = v0; tris[t++] = v0 + 1; tris[t++] = v0 + 2; tris[t++] = v0; tris[t++] = v0 + 2; tris[t++] = v0 + 3; Vector2 uvMax = theSlot.GetUVmax(border); Vector2 uvMin = theSlot.GetUVmin(border); uvs[v0].x = uvMin.x; uvs[v0].y = uvMax.y; uvs[v0 + 1].x = uvMax.x; uvs[v0 + 1].y = uvMax.y; uvs[v0 + 2].x = uvMax.x; uvs[v0 + 2].y = uvMin.y; uvs[v0 + 3].x = uvMin.x; uvs[v0 + 3].y = uvMin.y; }; NPVoxBox bounds = insetBox; Vector3 LDB = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.LeftDownBack) + (Vector3.left * npVoxToUnity.VoxeSize.x + Vector3.down * npVoxToUnity.VoxeSize.y + Vector3.back * npVoxToUnity.VoxeSize.z) * 0.5f; Vector3 RDB = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.RightDownBack) + (Vector3.right * npVoxToUnity.VoxeSize.x + Vector3.down * npVoxToUnity.VoxeSize.y + Vector3.back * npVoxToUnity.VoxeSize.z) * 0.5f; Vector3 LUB = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.LeftUpBack) + (Vector3.left * npVoxToUnity.VoxeSize.x + Vector3.up * npVoxToUnity.VoxeSize.y + Vector3.back * npVoxToUnity.VoxeSize.z) * 0.5f; Vector3 RUB = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.RightUpBack) + (Vector3.right * npVoxToUnity.VoxeSize.x + Vector3.up * npVoxToUnity.VoxeSize.y + Vector3.back * npVoxToUnity.VoxeSize.z) * 0.5f; Vector3 LDF = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.LeftDownForward) + (Vector3.left * npVoxToUnity.VoxeSize.x + Vector3.down * npVoxToUnity.VoxeSize.y + Vector3.forward * npVoxToUnity.VoxeSize.z) * 0.5f; Vector3 RDF = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.RightDownForward) + (Vector3.right * npVoxToUnity.VoxeSize.x + Vector3.down * npVoxToUnity.VoxeSize.y + Vector3.forward * npVoxToUnity.VoxeSize.z) * 0.5f; Vector3 LUF = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.LeftUpForward) + (Vector3.left * npVoxToUnity.VoxeSize.x + Vector3.up * npVoxToUnity.VoxeSize.y + Vector3.forward * npVoxToUnity.VoxeSize.z) * 0.5f; Vector3 RUF = cutoutOffset + npVoxToUnity.ToUnityPosition(bounds.RightUpForward) + (Vector3.right * npVoxToUnity.VoxeSize.x + Vector3.up * npVoxToUnity.VoxeSize.y + Vector3.forward * npVoxToUnity.VoxeSize.z) * 0.5f; if (downSlot != null) { v0 = v; vertices[v++] = LDB; vertices[v++] = RDB; vertices[v++] = RDF; vertices[v++] = LDF; addQuad(Vector3.down, downSlot); } if (upSlot != null) { v0 = v; vertices[v++] = RUB; vertices[v++] = LUB; vertices[v++] = LUF; vertices[v++] = RUF; addQuad(Vector3.up, upSlot); } if (forwardSlot != null) { v0 = v; vertices[v++] = LDF; vertices[v++] = RDF; vertices[v++] = RUF; vertices[v++] = LUF; addQuad(Vector3.forward, forwardSlot); } if (backSlot != null) { v0 = v; vertices[v++] = LUB; vertices[v++] = RUB; vertices[v++] = RDB; vertices[v++] = LDB; addQuad(Vector3.back, backSlot); } if (leftSlot != null) { v0 = v; vertices[v++] = LUF; vertices[v++] = LUB; vertices[v++] = LDB; vertices[v++] = LDF; addQuad(Vector3.left, leftSlot); } if (rightSlot != null) { v0 = v; vertices[v++] = RUB; vertices[v++] = RUF; vertices[v++] = RDF; vertices[v++] = RDB; addQuad(Vector3.right, rightSlot); } mesh.vertices = vertices; mesh.triangles = tris; mesh.uv = uvs; mesh.RecalculateBounds(); mesh.normals = normals; TangentSolver.Solve(mesh); // mesh.bounds = new Bounds( // insetOffset, // new Vector3( // bounds.Size.X * npVoxToUnity.VoxeSize.x, // bounds.Size.Y * npVoxToUnity.VoxeSize.y, // bounds.Size.Z * npVoxToUnity.VoxeSize.z // ) // ); Mesh sourceMesh = meshOutput.GetProduct(); mesh.bounds = sourceMesh.bounds; mesh.name = "zzz Cube Mesh "; return(mesh); } else { Debug.LogWarning("No Input set up"); if (mesh == null) { mesh = new Mesh(); } else { mesh.Clear(); } return(mesh); } }