void RenderModelsInVoxels(VoxelChunk chunk, FastList <ModelInVoxel> mivs)
        {
            instancingManager.ClearChunk(chunk);
            Quaternion rotation = Misc.quaternionZero;
            Vector3    position;

            for (int k = 0; k < mivs.count; k++)
            {
                ModelInVoxel    miv             = mivs.values [k];
                VoxelDefinition voxelDefinition = miv.vd;

                bool createGO = voxelDefinition.createGameObject || !voxelDefinition.gpuInstancing;

                if (createGO)
                {
                    VoxelPlaceholder placeholder = GetVoxelPlaceholder(chunk, miv.voxelIndex, true);
                    bool             createModel = true;
                    if (placeholder.modelInstance != null)
                    {
                        if (placeholder.modelTemplate != voxelDefinition.model)
                        {
                            DestroyImmediate(placeholder.modelInstance);
                        }
                        else
                        {
                            createModel = false;
                        }
                    }
                    MeshFilter mf;
                    Mesh       mesh = null;

                    if (createModel || placeholder.modelMeshFilter == null || placeholder.modelMeshFilter.sharedMesh == null || placeholder.modelMeshRenderer == null)
                    {
                        if (voxelDefinition.model == null)
                        {
                            continue;
                        }
                        placeholder.modelTemplate      = voxelDefinition.model;
                        placeholder.modelInstance      = Instantiate(voxelDefinition.model);
                        placeholder.modelInstance.name = "DynamicVoxelInstance";
                        // Note: placeHolder.modelInstance layer must be different from layerVoxels to allow dynamic voxels collide with terrain. So don't set its layer to layer voxels
                        placeholder.modelMeshRenderer = placeholder.modelInstance.GetComponent <MeshRenderer> ();
                        if (voxelDefinition.gpuInstancing)
                        {
                            if (placeholder.modelMeshRenderer != null)
                            {
                                placeholder.modelMeshRenderer.enabled = false;
                            }
                        }
                        else
                        {
                            mf = placeholder.modelMeshFilter = placeholder.modelInstance.GetComponent <MeshFilter> ();
                            if (mf != null)
                            {
                                mesh           = mf.sharedMesh = Instantiate <Mesh> (mf.sharedMesh);
                                mesh.hideFlags = HideFlags.DontSave;
                            }
                        }
                    }
                    else
                    {
                        mf = placeholder.modelMeshFilter;
                        if (mf != null)
                        {
                            mesh = mf.sharedMesh;
                        }
                    }

                    // Parent model to the placeholder
                    Transform tModel = placeholder.modelInstance.transform;
                    tModel.SetParent(placeholder.transform, false);
                    tModel.transform.localPosition = Misc.vector3zero;
                    tModel.transform.localScale    = voxelDefinition.scale;

                    if (voxelDefinition.gpuInstancing)
                    {
                        rotation = placeholder.transform.localRotation;
                    }
                    else
                    {
                        // Adjust lighting
                        if (effectiveGlobalIllumination || chunk.voxels [miv.voxelIndex].isColored)
                        {
                            // Update mesh colors
                            float   voxelLight = chunk.voxels [miv.voxelIndex].lightMesh / 15f;
                            Color32 color      = chunk.voxels [miv.voxelIndex].color;
                            color.r = (byte)(color.r * voxelLight);
                            color.g = (byte)(color.g * voxelLight);
                            color.b = (byte)(color.b * voxelLight);
                            modelMeshColors.Clear();
                            for (int c = 0; c < mesh.vertexCount; c++)
                            {
                                modelMeshColors.Add(color);
                            }
                            mesh.SetColors(modelMeshColors);
                            mesh.UploadMeshData(false);
                        }
                    }
                    if (!tModel.gameObject.activeSelf)
                    {
                        tModel.gameObject.SetActive(true);
                    }
                    position = placeholder.transform.position;
                }
                else
                {
                    // pure gpu instancing, no gameobject

                    position = GetVoxelPosition(chunk, miv.voxelIndex);

                    rotation = voxelDefinition.GetRotation(position);                      // deterministic rotation
                    // User rotation
                    float rot = chunk.voxels [miv.voxelIndex].GetTextureRotationDegrees();
                    if (rot != 0)
                    {
                        rotation *= Quaternion.Euler(0, rot, 0);
                    }

                    // Custom position
                    position = position + rotation * voxelDefinition.GetOffset(position);
                }

                if (voxelDefinition.gpuInstancing)
                {
                    instancingManager.AddVoxel(chunk, miv.voxelIndex, position, rotation, voxelDefinition.scale);
                }
            }
        }
Example #2
0
        void RenderModelsInVoxels(VoxelChunk chunk, FastList <ModelInVoxel> mivs)
        {
            instancedRenderer.ClearChunk(chunk);

            // deactivate all models in this chunk
            // we need to iterate the placeholders list entirely to address the case when the voxel is not using GPU instancing. In this case the gameobject renderer needs to be disabled
            // and we need to do this way because mivs won't contain the custom voxel since it may be termporarily converted to a transparent voxels due to see-through effect
            if (chunk.placeholders != null)
            {
                int count = chunk.placeholders.Count;
                for (int k = 0; k < count; k++)
                {
                    if (chunk.placeholders.entries [k].key >= 0)
                    {
                        VoxelPlaceholder placeHolder = chunk.placeholders.entries [k].value;
                        if (placeHolder != null)
                        {
                            placeHolder.ToggleRenderers(false);
                        }
                    }
                }
            }

            Quaternion rotation = Misc.quaternionZero;
            Vector3    position;

            for (int k = 0; k < mivs.count; k++)
            {
                ModelInVoxel    miv             = mivs.values [k];
                VoxelDefinition voxelDefinition = miv.vd;

                bool createGO = voxelDefinition.createGameObject || !voxelDefinition.gpuInstancing;

                if (VoxelIsHidden(chunk, miv.voxelIndex))
                {
                    continue;
                }

                if (createGO)
                {
                    VoxelPlaceholder placeholder = GetVoxelPlaceholder(chunk, miv.voxelIndex, true);
                    bool             createModel = true;
                    if (placeholder.modelInstance != null)
                    {
                        if (placeholder.modelTemplate != voxelDefinition.prefab)
                        {
                            DestroyImmediate(placeholder.modelInstance);
                            placeholder.originalMeshColors32 = null;
                            placeholder.lastMivTintColor     = Misc.color32White;
                        }
                        else
                        {
                            createModel = false;
                        }
                    }

                    if (createModel || placeholder.modelInstance == null)
                    {
                        if (voxelDefinition.prefab == null)
                        {
                            continue;
                        }
                        placeholder.modelTemplate      = voxelDefinition.prefab;
                        placeholder.modelInstance      = Instantiate(voxelDefinition.prefab);
                        placeholder.modelInstance.name = "DynamicVoxelInstance";
                        // Note: placeHolder.modelInstance layer must be different from layerVoxels to allow dynamic voxels collide with terrain. So don't set its layer to layer voxels
                        placeholder.modelMeshRenderers = placeholder.modelInstance.GetComponentsInChildren <MeshRenderer> ();
                        if (voxelDefinition.gpuInstancing)
                        {
                            placeholder.ToggleRenderers(false);
                        }
                        else
                        {
                            placeholder.modelMeshFilter = placeholder.modelInstance.GetComponentInChildren <MeshFilter> (true);
                        }

                        // Parent model to the placeholder
                        Transform tModel = placeholder.modelInstance.transform;
                        tModel.SetParent(placeholder.transform, false);
                        tModel.transform.localPosition = Misc.vector3zero;
                        tModel.transform.localScale    = voxelDefinition.scale;
                    }
                    else
                    {
                        placeholder.ToggleRenderers(true);
                    }

                    if (voxelDefinition.gpuInstancing)
                    {
                        rotation = placeholder.transform.localRotation;
                    }
                    else
                    {
                        // Adjust lighting
                        if (effectiveGlobalIllumination || chunk.voxels [miv.voxelIndex].isColored)
                        {
                            // Update mesh colors
                            MeshFilter mf = placeholder.modelMeshFilter;
                            if (mf != null)
                            {
                                Mesh mesh = mf.sharedMesh;
                                if (mesh != null)
                                {
                                    Color32 tintColor = chunk.voxels [miv.voxelIndex].color;
                                    tintColor.a = (byte)(chunk.voxels[miv.voxelIndex].lightMesh + (chunk.voxels[miv.voxelIndex].torchLight << 4));
                                    if (placeholder.lastMivTintColor.a != tintColor.a || placeholder.lastMivTintColor.r != tintColor.r || placeholder.lastMivTintColor.g != tintColor.g || placeholder.lastMivTintColor.b != tintColor.b)
                                    {
                                        mf.sharedMesh = BakeMeshLighting(mf, tintColor);
                                        placeholder.lastMivTintColor = tintColor;
                                    }
                                }
                            }
                        }
                    }
                    if (!placeholder.modelInstance.gameObject.activeSelf)
                    {
                        placeholder.modelInstance.gameObject.SetActive(true);
                    }
                    position = placeholder.transform.position;
                }
                else
                {
                    // pure gpu instancing, no gameobject

                    position = GetVoxelPosition(chunk, miv.voxelIndex);

                    rotation = voxelDefinition.GetRotation(position);  // deterministic rotation
                                                                       // User rotation
                    float rot = chunk.voxels [miv.voxelIndex].GetTextureRotationDegrees();
                    if (rot != 0)
                    {
                        rotation *= Quaternion.Euler(0, rot, 0);
                    }

                    // Custom position
                    position += rotation * voxelDefinition.GetOffset(position);
                }

                if (voxelDefinition.gpuInstancing)
                {
                    instancedRenderer.AddVoxel(chunk, miv.voxelIndex, position, rotation, voxelDefinition.scale);
                }
            }
        }