private void DrawPaint(VoxelFace paint, Rect rect) { float rotation = VoxelFace.GetOrientationRotation(paint.orientation) * 90; Vector2 scaleFactor = Vector2.one; if (VoxelFace.GetOrientationMirror(paint.orientation)) { scaleFactor = new Vector2(-1, 1); rotation += 90; } Matrix4x4 baseMatrix = GUI.matrix; RotateAboutPoint(rect.center, rotation, scaleFactor); MaterialSelectorGUI.DrawMaterialTexture(paint.material, rect, false); MaterialSelectorGUI.DrawMaterialTexture(paint.overlay, rect, true); GUI.matrix = baseMatrix; }
private void Orient(byte change) { int changeRotation = VoxelFace.GetOrientationRotation(change); bool changeFlip = VoxelFace.GetOrientationMirror(change); int paintRotation = VoxelFace.GetOrientationRotation(paint.orientation); bool paintFlip = VoxelFace.GetOrientationMirror(paint.orientation); if (paintFlip ^ changeFlip) { paintRotation += 4 - changeRotation; } else { paintRotation += changeRotation; } if (changeFlip) { paintFlip = !paintFlip; } paint.orientation = VoxelFace.Orientation(paintRotation, paintFlip); handler(paint); }
public void UpdateVoxel() { bool inEditor = InEditor(); Material coloredHighlightMaterial = null; if (substance != null && substance.highlight != Color.clear) { coloredHighlightMaterial = substance.highlightMaterial; } bool xRay = false; if (substance != null && inEditor) { xRay = substance.xRay; } if (xRay) { gameObject.layer = 8; // XRay layer } else { gameObject.layer = 0; // default } int numFilledFaces = 0; foreach (VoxelFace f in faces) { if (!f.IsEmpty()) { numFilledFaces++; } } var vertices = new Vector3[numFilledFaces * 4]; var uvs = new Vector2[numFilledFaces * 4]; var normals = new Vector3[numFilledFaces * 4]; var tangents = new Vector4[numFilledFaces * 4]; float[] vertexPos = new float[3]; // reusable numFilledFaces = 0; int numMaterials = 0; for (int faceNum = 0; faceNum < 6; faceNum++) { VoxelFace face = faces[faceNum]; if (face.IsEmpty()) { continue; } int axis = FaceIAxis(faceNum); Vector3 normal = DirectionForFaceI(faceNum); int rotation = VoxelFace.GetOrientationRotation(face.orientation); bool mirrored = VoxelFace.GetOrientationMirror(face.orientation); // ST space is always upright Vector3 positiveS_xyz = POSITIVE_S_XYZ[faceNum]; // positive S in XYZ space Vector3 positiveT_xyz = POSITIVE_T_XYZ[faceNum]; int uRot = rotation; if (mirrored) { uRot += 3; } int vRot; if (!mirrored) { vRot = uRot + 3; } else { vRot = uRot + 1; } Vector2 positiveU_st = POSITIVE_U_ST[uRot % 4]; Vector2 positiveV_st = POSITIVE_U_ST[vRot % 4]; Vector3 positiveU_xyz = positiveS_xyz * positiveU_st.x + positiveT_xyz * positiveU_st.y; Vector3 positiveV_xyz = positiveS_xyz * positiveV_st.x + positiveT_xyz * positiveV_st.y; Vector4 tangent = new Vector4(positiveU_xyz.x, positiveU_xyz.y, positiveU_xyz.z, mirrored ? 1 : -1); // example for faceNum = 5 (z min) // 0 bottom left // 1 bottom right // 2 top right // 3 top left for (int i = 0; i < 4; i++) { int vertexI = numFilledFaces * 4 + i; vertexPos[axis] = faceNum % 2; vertexPos[(axis + 1) % 3] = SQUARE_LOOP[i].x; vertexPos[(axis + 2) % 3] = SQUARE_LOOP[i].y; Vector3 vertex = new Vector3(vertexPos[0], vertexPos[1], vertexPos[2]); vertices[vertexI] = vertex; normals[vertexI] = normal; tangents[vertexI] = tangent; vertex += transform.position; Vector2 uv = new Vector2( vertex.x * positiveU_xyz.x + vertex.y * positiveU_xyz.y + vertex.z * positiveU_xyz.z, vertex.x * positiveV_xyz.x + vertex.y * positiveV_xyz.y + vertex.z * positiveV_xyz.z); uvs[vertexI] = uv; } numFilledFaces++; if (xRay) { numMaterials++; } else { if (face.material != null) { numMaterials++; } if (face.overlay != null) { numMaterials++; } } if (coloredHighlightMaterial != null) { numMaterials++; } if (face.addSelected || face.storedSelected) { numMaterials++; } } Mesh mesh = GetComponent <MeshFilter>().mesh; mesh.name = "Voxel Mesh"; mesh.Clear(); mesh.vertices = vertices; mesh.uv = uvs; mesh.normals = normals; mesh.tangents = tangents; mesh.subMeshCount = numMaterials; Material[] materials = new Material[numMaterials]; numFilledFaces = 0; numMaterials = 0; for (int faceI = 0; faceI < 6; faceI++) { VoxelFace face = faces[faceI]; if (face.IsEmpty()) { continue; } var triangles = new int[6]; if (faceI % 2 == 1) { triangles[0] = numFilledFaces * 4 + 0; triangles[1] = numFilledFaces * 4 + 1; triangles[2] = numFilledFaces * 4 + 2; triangles[3] = numFilledFaces * 4 + 0; triangles[4] = numFilledFaces * 4 + 2; triangles[5] = numFilledFaces * 4 + 3; } else { triangles[0] = numFilledFaces * 4 + 0; triangles[1] = numFilledFaces * 4 + 2; triangles[2] = numFilledFaces * 4 + 1; triangles[3] = numFilledFaces * 4 + 0; triangles[4] = numFilledFaces * 4 + 3; triangles[5] = numFilledFaces * 4 + 2; } if (xRay) { materials[numMaterials] = xRayMaterial; mesh.SetTriangles(triangles, numMaterials); numMaterials++; } else { if (face.material != null) { materials[numMaterials] = face.material; mesh.SetTriangles(triangles, numMaterials); numMaterials++; } if (face.overlay != null) { materials[numMaterials] = face.overlay; mesh.SetTriangles(triangles, numMaterials); numMaterials++; } } if (coloredHighlightMaterial != null) { materials[numMaterials] = coloredHighlightMaterial; mesh.SetTriangles(triangles, numMaterials); numMaterials++; } if (face.addSelected || face.storedSelected) { materials[numMaterials] = selectedMaterial; mesh.SetTriangles(triangles, numMaterials); numMaterials++; } numFilledFaces++; } Renderer renderer = GetComponent <Renderer>(); renderer.materials = materials; MeshCollider meshCollider = GetComponent <MeshCollider>(); BoxCollider boxCollider = GetComponent <BoxCollider>(); if (inEditor) { renderer.enabled = true; meshCollider.enabled = true; // force the collider to update. It otherwise might not since we're using the same mesh object // this fixes a bug where rays would pass through a voxel that used to be empty meshCollider.sharedMesh = null; meshCollider.sharedMesh = mesh; boxCollider.enabled = false; } else { boxCollider.enabled = true; if (substance == null && !IsEmpty()) // a wall { renderer.enabled = true; boxCollider.isTrigger = false; } else if (substance != null) { renderer.enabled = false; boxCollider.isTrigger = true; } else // probably an object { renderer.enabled = false; boxCollider.enabled = false; } meshCollider.sharedMesh = null; meshCollider.enabled = false; } } // end UpdateVoxel()