示例#1
0
        void AddVoxelTextures(VoxelDefinition vd)
        {
            if (vd == null)
            {
                return;
            }

            if (vd.index > 0 && vd.index < voxelDefinitionsCount && voxelDefinitions [vd.index] == vd)
            {
                return;                 // already added
            }
            // Resize voxel definitions array?
            if (voxelDefinitionsCount >= voxelDefinitions.Length)
            {
                VoxelDefinition[] resized = new VoxelDefinition[voxelDefinitions.Length * 2];
                for (int k = 0; k < voxelDefinitionsCount; k++)
                {
                    resized [k] = voxelDefinitions [k];
                }
                voxelDefinitions = resized;
            }

            voxelDefinitions [voxelDefinitionsCount] = vd;
            vd.index = (ushort)voxelDefinitionsCount;
            voxelDefinitionsCount++;
            voxelDefinitionsDict [vd.name] = vd;

            // Autofix certain non supported properties
            if (vd.navigatable)
            {
                vd.navigatable = vd.renderType.supportsNavigation();
            }

            // Check if custom model has collider
            vd.modelUsesCollider = false;
            if (vd.renderType == RenderType.Custom)
            {
                if (vd.model == null)
                {
                    // custom voxel is missing model so we assign a default cube
                    vd.model  = GetDefaultVoxelPrefab();
                    vd.opaque = 15;
                }
                if (vd.model != null)
                {
                    // annotate if model has collider
                    if (vd.gpuInstancing)
                    {
                        if (vd.createGameObject)
                        {
                            vd.modelUsesCollider = vd.model.GetComponent <Collider> () != null;
                        }
                    }
                    else
                    {
                        vd.modelUsesCollider = vd.model.GetComponent <Collider> () != null;
                    }
                }
                if (vd.textureSide == null)
                {
                    // assign default texture sample for inventory icons
                    Material modelMaterial = vd.material;
                    if (modelMaterial != null && modelMaterial.mainTexture != null && modelMaterial.mainTexture is Texture2D)
                    {
                        vd.icon = (Texture2D)modelMaterial.mainTexture;
                    }
                }
            }

            // Assign default material
            Material mat = vd.GetOverrideMaterial(effectiveUseGeometryShaders);

            if (mat == null)
            {
                switch (vd.renderType)
                {
                case RenderType.Opaque:
                case RenderType.Opaque6tex:
                    vd.materialBufferIndex = INDICES_BUFFER_OPAQUE;
                    break;

                case RenderType.Cutout:
                    vd.materialBufferIndex = INDICES_BUFFER_CUTOUT;
                    break;

                case RenderType.CutoutCross:
                    vd.materialBufferIndex = INDICES_BUFFER_CUTXSS;
                    break;

                case RenderType.Water:
                    vd.materialBufferIndex = INDICES_BUFFER_WATER;
                    break;

                case RenderType.Transp6tex:
                    vd.materialBufferIndex = INDICES_BUFFER_TRANSP;
                    break;

                case RenderType.OpaqueNoAO:
                    vd.materialBufferIndex = INDICES_BUFFER_OPNOAO;
                    break;
                }
            }
            else
            {
                // Assign material index
                int materialBufferIndex;
                if (!materialIndices.TryGetValue(mat, out materialBufferIndex))
                {
                    if (lastBufferIndex < materials.Length - 1)
                    {
                        lastBufferIndex++;
                        materialIndices [mat]       = lastBufferIndex;
                        materials [lastBufferIndex] = Instantiate <Material> (mat);
                    }
                    else
                    {
                        Debug.LogError("Too many override materials. Max materials supported = " + MAX_MATERIALS_PER_CHUNK);
                    }
                    materialBufferIndex = lastBufferIndex;
                }
                vd.materialBufferIndex = materialBufferIndex;
            }

            // Compute voxel definition texture indices including rotations
            bool supportsEmission = vd.renderType.supportsEmission();

            vd.textureIndexTop    = AddTexture(vd.textureTop, supportsEmission ? vd.textureTopEmission : null, vd.textureTopNRM, vd.textureTopDISP);
            vd.textureIndexSide   = AddTexture(vd.textureSide, supportsEmission ? vd.textureSideEmission : null, vd.textureSideNRM, vd.textureSideDISP);
            vd.textureIndexBottom = AddTexture(vd.textureBottom, supportsEmission ? vd.textureBottomEmission : null, vd.textureBottomNRM, vd.textureBottomDISP);
            vd.textureSideIndices = new TextureRotationIndices[4];
            if (vd.renderType.numberOfTextures() == 6)
            {
                int textureIndexRight   = AddTexture(vd.textureRight, supportsEmission ? vd.textureRightEmission : null, vd.textureRightNRM, vd.textureRightDISP);
                int textureIndexForward = AddTexture(vd.textureForward, supportsEmission ? vd.textureForwardEmission : null, vd.textureForwardNRM, vd.textureForwardDISP);
                int textureIndexLeft    = AddTexture(vd.textureLeft, supportsEmission ? vd.textureLeftEmission : null, vd.textureLeftNRM, vd.textureLeftDISP);

                // Rotated texture indices. In geometry shaders, lower 12 bits are combined with upper bits to define texture indices (2 texture indices per field)
                // x = side + forward, y = top + right, z = bottom + left
                if (effectiveUseGeometryShaders)
                {
                    vd.textureSideIndices [0] = new TextureRotationIndices {
                        xyzw = new Vector4(vd.textureIndexSide + (textureIndexForward << 12), vd.textureIndexTop + (textureIndexRight << 12), vd.textureIndexBottom + (textureIndexLeft << 12), 0)
                    };
                    vd.textureSideIndices [1] = new TextureRotationIndices {
                        xyzw = new Vector4(textureIndexRight + (textureIndexLeft << 12), vd.textureIndexTop + (textureIndexForward << 12), vd.textureIndexBottom + (vd.textureIndexSide << 12), 0)
                    };
                    vd.textureSideIndices [2] = new TextureRotationIndices {
                        xyzw = new Vector4(textureIndexForward + (vd.textureIndexSide << 12), vd.textureIndexTop + (textureIndexLeft << 12), vd.textureIndexBottom + (textureIndexRight << 12), 0)
                    };
                    vd.textureSideIndices [3] = new TextureRotationIndices {
                        xyzw = new Vector4(textureIndexLeft + (textureIndexLeft << 12), vd.textureIndexTop + (vd.textureIndexSide << 12), vd.textureIndexBottom + (textureIndexForward << 12), 0)
                    };
                }
                else
                {
                    vd.textureSideIndices [0] = new TextureRotationIndices {
                        forward = textureIndexForward, right = textureIndexRight, back = vd.textureIndexSide, left = textureIndexLeft
                    };
                    vd.textureSideIndices [1] = new TextureRotationIndices {
                        forward = textureIndexLeft, right = textureIndexForward, back = textureIndexRight, left = textureIndexForward
                    };
                    vd.textureSideIndices [2] = new TextureRotationIndices {
                        forward = vd.textureIndexSide, right = textureIndexLeft, back = textureIndexForward, left = textureIndexRight
                    };
                    vd.textureSideIndices [3] = new TextureRotationIndices {
                        forward = textureIndexRight, right = vd.textureIndexSide, back = textureIndexLeft, left = vd.textureIndexSide
                    };
                }
            }
            else
            {
                if (effectiveUseGeometryShaders)
                {
                    vd.textureSideIndices [0] = vd.textureSideIndices [1] = vd.textureSideIndices [2] = vd.textureSideIndices [3] = new TextureRotationIndices {
                        xyzw = new Vector4(vd.textureIndexSide + (vd.textureIndexSide << 12), vd.textureIndexTop + (vd.textureIndexSide << 12), vd.textureIndexBottom + (vd.textureIndexSide << 12), 0)
                    };
                }
                else
                {
                    vd.textureSideIndices [0] = vd.textureSideIndices [1] = vd.textureSideIndices [2] = vd.textureSideIndices [3] = new TextureRotationIndices {
                        forward = vd.textureIndexSide, right = vd.textureIndexSide, back = vd.textureIndexSide, left = vd.textureIndexSide
                    };
                }
            }

            if (vd.renderType == RenderType.CutoutCross && vd.sampleColor.a == 0)
            {
                AnalyzeGrassTexture(vd, vd.textureSide);
            }
            else
            {
                if (vd.textureIndexSide > 0)
                {
                    Color32[] colors = worldTextures [vd.textureIndexSide].colorsAndEmission;
                    vd.sampleColor = colors [Random.Range(0, colors.Length)];
                }
            }

            GetVoxelThumbnails(vd);
        }
        void AddVoxelTextures(VoxelDefinition vd)
        {
            if (!AppendVoxelDefinition(vd))
            {
                return;
            }


            // Autofix certain non supported properties
            if (vd.navigatable)
            {
                vd.navigatable = vd.renderType.supportsNavigation();
            }

            // Check if custom model has collider
            vd.prefabUsesCollider = false;
            if (vd.renderType == RenderType.Custom)
            {
                if (vd.model == null)
                {
                    // custom voxel is missing model so we assign a default cube
                    vd.model = GetDefaultVoxelPrefab();
                }
                vd.prefab = vd.model;
                if (vd.model != null)
                {
                    if (vd.prefabMaterial != CustomVoxelMaterial.PrefabMaterial)
                    {
                        Material instancingMat = null;
                        switch (vd.prefabMaterial)
                        {
                        case CustomVoxelMaterial.VertexLit: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model VertexLit"); break;

                        case CustomVoxelMaterial.Texture: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture"); break;

                        case CustomVoxelMaterial.TextureAlpha: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Alpha"); break;

                        case CustomVoxelMaterial.TextureAlphaDoubleSided: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Alpha Double Sided"); break;

                        case CustomVoxelMaterial.TextureTriplanar: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Triplanar"); break;

                        case CustomVoxelMaterial.TextureCutout: instancingMat = Resources.Load <Material> ("VoxelPlay/Materials/VP Model Texture Cutout"); break;
                        }
                        if (instancingMat != null)
                        {
                            instancingMat = Instantiate <Material> (instancingMat);
                            vd.prefab     = Instantiate <GameObject> (vd.model);
                            vd.prefab.SetActive(false);
                            vd.prefab.transform.SetParent(transform, false);
                            Renderer [] rr = vd.prefab.GetComponentsInChildren <Renderer> ();
                            for (int k = 0; k < rr.Length; k++)
                            {
                                Material refMat = rr [k].sharedMaterial;
                                if (refMat != null)
                                {
                                    if (refMat.HasProperty("_Color") && instancingMat.HasProperty("_Color"))
                                    {
                                        instancingMat.SetColor("_Color", refMat.GetColor("_Color"));
                                    }
                                    if (refMat.HasProperty("_MainTex") && instancingMat.HasProperty("_MainTex"))
                                    {
                                        instancingMat.SetTexture("_MainTex", refMat.GetTexture("_MainTex"));
                                    }
                                    if (refMat.HasProperty("_BumpMap") && instancingMat.HasProperty("_BumpMap"))
                                    {
                                        instancingMat.SetTexture("_BumpMap", refMat.GetTexture("_BumpMap"));
                                    }
                                }
                                rr [k].sharedMaterial = instancingMat;
                            }
                        }
                    }
                    // annotate if model has collider
                    Collider prefabCollider    = vd.prefab.GetComponentInChildren <Collider> ();
                    bool     hasPrefabCollider = prefabCollider != null;
                    if (vd.gpuInstancing)
                    {
                        if (vd.createGameObject)
                        {
                            vd.prefabUsesCollider = hasPrefabCollider;
                        }
                    }
                    else
                    {
                        vd.prefabUsesCollider = hasPrefabCollider;
                    }
                    if (hasPrefabCollider && applicationIsPlaying && prefabCollider is BoxCollider)
                    {
                        StartCoroutine(ComputePrefabBoxColliderBounds(vd));
                    }
                }
                if (vd.textureSide == null)
                {
                    // assign default texture sample for inventory icons
                    Material modelMaterial = vd.material;
                    if (modelMaterial != null && modelMaterial.mainTexture != null && modelMaterial.mainTexture is Texture2D)
                    {
                        vd.icon = (Texture2D)modelMaterial.mainTexture;
                    }
                }
            }

            // Assign default material
            Material mat = vd.GetOverrideMaterial();

            if (mat == null)
            {
                switch (vd.renderType)
                {
                case RenderType.Opaque:
                case RenderType.Opaque6tex:
                    vd.materialBufferIndex = INDICES_BUFFER_OPAQUE;
                    break;

                case RenderType.OpaqueAnimated:
                    vd.materialBufferIndex = INDICES_BUFFER_OPANIM;
                    break;

                case RenderType.Cutout:
                    vd.materialBufferIndex = INDICES_BUFFER_CUTOUT;
                    break;

                case RenderType.CutoutCross:
                    vd.materialBufferIndex = INDICES_BUFFER_CUTXSS;
                    break;

                case RenderType.Water:
                    vd.materialBufferIndex = INDICES_BUFFER_WATER;
                    break;

                case RenderType.Transp6tex:
                    vd.materialBufferIndex = INDICES_BUFFER_TRANSP;
                    break;

                case RenderType.Cloud:
                    vd.materialBufferIndex = INDICES_BUFFER_CLOUD;
                    break;

                case RenderType.OpaqueNoAO:
                    vd.materialBufferIndex = INDICES_BUFFER_OPNOAO;
                    break;
                }
            }
            else
            {
                // Assign material index
                int materialBufferIndex;
                if (!materialIndices.TryGetValue(mat, out materialBufferIndex))
                {
                    if (lastBufferIndex < renderingMaterials.Length - 1)
                    {
                        lastBufferIndex++;
                        materialIndices [mat] = lastBufferIndex;
                        if (vd.texturesByMaterial)
                        {
                            renderingMaterials [lastBufferIndex].material         = mat;
                            renderingMaterials [lastBufferIndex].usesTextureArray = false;
                        }
                        else
                        {
                            renderingMaterials [lastBufferIndex].material         = Instantiate <Material> (mat);
                            renderingMaterials [lastBufferIndex].usesTextureArray = true;
                        }
                    }
                    else
                    {
                        Debug.LogError("Too many override materials. Max materials supported = " + MAX_MATERIALS_PER_CHUNK);
                    }
                    materialBufferIndex = lastBufferIndex;
                }
                vd.materialBufferIndex = materialBufferIndex;
            }

            // Compute voxel definition texture indices including rotations
            bool supportsEmission = vd.renderType.supportsEmission();
            bool animated         = vd.renderType.supportsTextureAnimation();

            vd.textureIndexTop = AddTexture(vd.textureTop, supportsEmission ? vd.textureTopEmission : null, vd.textureTopNRM, vd.textureTopDISP, !animated);
            if (animated)
            {
                for (int k = 0; k < vd.animationTextures.Length; k++)
                {
                    AddTexture(vd.animationTextures [k].textureTop != null ? vd.animationTextures [k].textureTop : vd.textureTop, null, null, null, false);
                }
            }
            vd.textureIndexSide = AddTexture(vd.textureSide, supportsEmission ? vd.textureSideEmission : null, vd.textureSideNRM, vd.textureSideDISP, !animated);
            if (animated)
            {
                for (int k = 0; k < vd.animationTextures.Length; k++)
                {
                    AddTexture(vd.animationTextures [k].textureSide != null ? vd.animationTextures [k].textureSide : vd.textureSide, null, null, null, false);
                }
            }
            vd.textureIndexBottom = AddTexture(vd.textureBottom, supportsEmission ? vd.textureBottomEmission : null, vd.textureBottomNRM, vd.textureBottomDISP, !animated);
            if (animated)
            {
                for (int k = 0; k < vd.animationTextures.Length; k++)
                {
                    AddTexture(vd.animationTextures [k].textureBottom != null ? vd.animationTextures [k].textureBottom : vd.textureBottom, null, null, null, false);
                }
            }
            if (vd.textureSideIndices == null || vd.textureSideIndices.Length != 4)
            {
                vd.textureSideIndices = new TextureRotationIndices [4];
            }

            if (vd.renderType.numberOfTextures() == 6)
            {
                int textureIndexRight   = vd.textureIndexRight = AddTexture(vd.textureRight, supportsEmission ? vd.textureRightEmission : null, vd.textureRightNRM, vd.textureRightDISP);
                int textureIndexForward = vd.textureIndexForward = AddTexture(vd.textureForward, supportsEmission ? vd.textureForwardEmission : null, vd.textureForwardNRM, vd.textureForwardDISP);
                int textureIndexLeft    = vd.textureIndexLeft = AddTexture(vd.textureLeft, supportsEmission ? vd.textureLeftEmission : null, vd.textureLeftNRM, vd.textureLeftDISP);

                vd.textureSideIndices [0] = new TextureRotationIndices {
                    forward = textureIndexForward,
                    right   = textureIndexRight,
                    back    = vd.textureIndexSide,
                    left    = textureIndexLeft
                };
                vd.textureSideIndices [1] = new TextureRotationIndices {
                    forward = textureIndexLeft,
                    right   = textureIndexForward,
                    back    = textureIndexRight,
                    left    = vd.textureIndexSide
                };
                vd.textureSideIndices [2] = new TextureRotationIndices {
                    forward = vd.textureIndexSide,
                    right   = textureIndexLeft,
                    back    = textureIndexForward,
                    left    = textureIndexRight
                };
                vd.textureSideIndices [3] = new TextureRotationIndices {
                    forward = textureIndexRight,
                    right   = vd.textureIndexSide,
                    back    = textureIndexLeft,
                    left    = textureIndexForward
                };
            }
            else
            {
                vd.textureSideIndices [0] = vd.textureSideIndices [1] = vd.textureSideIndices [2] = vd.textureSideIndices [3] = new TextureRotationIndices {
                    forward = vd.textureIndexSide,
                    right   = vd.textureIndexSide,
                    back    = vd.textureIndexSide,
                    left    = vd.textureIndexSide
                };
            }

            if (vd.renderType == RenderType.CutoutCross && vd.sampleColor.a == 0)
            {
                AnalyzeGrassTexture(vd, vd.textureSample != null ? vd.textureSample : vd.textureSide);
            }
            else
            {
                if (vd.textureSample != null)
                {
                    Color32 [] colors = vd.textureSample.GetPixels32();
                    vd.sampleColor = colors [Random.Range(0, colors.Length)];
                }
                else if (vd.textureIndexSide > 0)
                {
                    Color32 [] colors = worldTextures [vd.textureIndexSide].colorsAndEmission;
                    vd.sampleColor = colors [Random.Range(0, colors.Length)];
                }
            }

            GetVoxelThumbnails(vd);
        }