Esempio n. 1
0
    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;
    }
Esempio n. 2
0
    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);
    }
Esempio n. 3
0
    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()