Beispiel #1
0
 public void SpawnDebris(VoxelObject data, Transform source, Vector3 sprayDirection, int skip = 1)
 {
     foreach (var voxelData in data.m_VoxelData)
     {
         SpawnDebris(data, voxelData, source.position, source.rotation, sprayDirection.normalized, skip);
     }
 }
Beispiel #2
0
    private void SpawnDebris(VoxelObject sourceData, VoxelData data, Vector3 position, Quaternion rotation, Vector3 sprayDirection, int skip)
    {
        int counter = 0;

        for (int x = 0; x < data.Width; ++x)
        {
            for (int y = 0; y < data.Height; ++y)
            {
                for (int z = 0; z < data.Depth; ++z)
                {
                    Voxel voxel = data.GetVoxel(x, y, z);

                    if (!voxel.IsEmpty && ((++counter) % skip) == 0)
                    {
                        Color colour = m_AtlasTexture.GetPixel((int)voxel.m_ColourIndex - 1, 0);

                        VoxelDebris debris = VoxelDebris.NewDebris(m_DebrisType, sourceData, voxel, m_DebrisLifetime, position + rotation * data.GetVoxelPosition(x, y, z, sourceData.m_Scale), rotation);

                        debris.SetColour(colour);
                        debris.ApplyExplostion(m_ExplosiveForce, position, sprayDirection);
                    }
                }
            }
        }
    }
Beispiel #3
0
        public static bool Load(string path, out VoxelObject vo)
        {
            path = Path.Combine(GLoader.RootDirectory, path);

            // Check if file exists
            if (!File.Exists(path))
            {
                vo = null;
                return(false);
            }

            // Load file
            try
            {
                using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)))
                {
                    VoxelObjectFileHeader header = new VoxelObjectFileHeader(reader);
                    IVoxelObjectFileIO    io     = GetIOFromHeader(header);

                    if (io == null)
                    {
                        throw new VoxelIOException("Failed to get IO for VoxelObject File! Header: " + header.ToString());
                    }
                    else
                    {
                        return(io.Load(reader, out vo));
                    }
                }
            }
            catch (FileNotFoundException)
            {
                vo = null;
                return(false);
            }
        }
Beispiel #4
0
 public void SpawnDebris(VoxelObject data, Vector3 position, Quaternion rotation, Vector3 sprayDirection, int skip = 1)
 {
     foreach (var voxelData in data.m_VoxelData)
     {
         SpawnDebris(data, voxelData, position, rotation, sprayDirection, skip);
     }
 }
Beispiel #5
0
    private void UpdateData()
    {
        if (m_VoxelData != m_PreviousVoxelData)
        {
            m_PreviousVoxelData = m_VoxelData;

            for (int i = 0; i < transform.childCount; ++i)
            {
                GameObject child = transform.GetChild(i).gameObject;
                if (child.CompareTag("Generated"))
                {
                    DestroyImmediate(transform.GetChild(i).gameObject);
                }
            }

            if (m_VoxelData != null && m_VoxelData.m_ModelObject != null)
            {
                GameObject gameObj = Instantiate(m_VoxelData.m_ModelObject, transform);
                HideFlags  flags   = HideFlags.DontSave;

#if UNITY_EDITOR
                bool isPrefabSource = gameObject.scene.rootCount == 1;

                if (isPrefabSource)
                {
                    flags = HideFlags.HideAndDontSave;
                }
#endif

                UpdateFlags(gameObj.transform, flags);
            }
        }
    }
Beispiel #6
0
    public override void OnImportAsset(AssetImportContext ctx)
    {
        int counter = 0;

        // Main import object
        VoxelObject importObject = ScriptableObject.CreateInstance <VoxelObject>();

        importObject.m_Scale = m_Scale;
        importObject.name    = Path.GetFileNameWithoutExtension(ctx.assetPath);

        ctx.AddObjectToAsset(importObject.name, importObject);
        ctx.SetMainObject(importObject);

        // Main game import object
        GameObject rootObject = new GameObject();

        rootObject.name = importObject.name;

        ctx.AddObjectToAsset(rootObject.name, rootObject);
        importObject.m_ModelObject = rootObject;

        List <VoxelData> allData = new List <VoxelData>();

        foreach (string voxFile in Directory.EnumerateFiles(Path.GetDirectoryName(ctx.assetPath), importObject.name + "*.vox"))
        {
            ctx.DependsOnSourceAsset(voxFile);

            // Add all separate data with model and voxel data
            Color32[] palette;
            foreach (VoxelData data in VoxelData.ParseFrom(voxFile, out palette))
            {
                allData.Add(data);

                data.name = "VOX_" + importObject.name + "_" + counter;
                ctx.AddObjectToAsset(data.name, data);

                Mesh mesh = data.GenerateMesh(m_PivotOffset, m_Scale);
                mesh.name = "MDL_" + importObject.name + "_" + counter;
                ctx.AddObjectToAsset(mesh.name, mesh);

                // Setup a game object to hold this
                GameObject modelObject = new GameObject();
                modelObject.name = "OBJ_" + importObject.name + "_" + counter;

                MeshFilter   meshFilter = modelObject.AddComponent <MeshFilter>();
                MeshRenderer renderer   = modelObject.AddComponent <MeshRenderer>();

                meshFilter.mesh   = mesh;
                renderer.material = m_SourceMaterial;

                modelObject.transform.SetParent(rootObject.transform);
                ctx.AddObjectToAsset(modelObject.name, modelObject);

                ++counter;
            }
        }

        importObject.m_VoxelData = allData.ToArray();
    }
Beispiel #7
0
 public void RemoveVoxelObject(VoxelObject voxel_obj)
 {
     if (!voxel_obj)
     {
         return;
     }
     voxel_objs.Remove(voxel_obj);
 }
Beispiel #8
0
        /// <summary>
        /// Create a new chunk for the given voxel object at the given chunk position
        /// </summary>
        /// <param name="voxObj">The voxel object</param>
        /// <param name="chunkPosition">The position of the chunk</param>
        public Chunk(VoxelObject voxObj, IntVector3 chunkPosition)
        {
            VoxelObject   = voxObj;
            ChunkPosition = chunkPosition;

            // Create voxels
            CreateVoxels();
        }
Beispiel #9
0
        public VoxelEditorObject(VoxelObject original)
            : this(original.Width, original.Height, original.Depth, original.CubeSize, true)
        {
            Blocks = original.Blocks;

            CalculateMinMax();
            RecountBlocks();
            BuildMesh();
        }
    private void OnEnable()
    {
        Debug.Log("Tester Thing Started");
        CreateChunkContainer();

        VoxelObjectSettings settings = new VoxelObjectSettings(16, 1);

        voxelObject = new VoxelObject(settings);
        StartCoroutine(CreateChunks());
    }
Beispiel #11
0
 /// <summary>
 /// Returns true if the face of the voxel at the given position is solid
 /// </summary>
 /// <param name="localPos">The local position of the voxel</param>
 /// <param name="dir">The direction of the face</param>
 /// <returns></returns>
 public bool IsSolid(IntVector3 localPos, OrdinalDirections dir)
 {
     if (IsInChunk(localPos.X, localPos.Y, localPos.Z))
     {
         return(voxels[localPos.X, localPos.Y, localPos.Z].IsSolid(dir));
     }
     else
     {
         return(VoxelObject.IsSolid(VoxelObject.PosHelper.ChunkToObjectPosition(ChunkPosition) + localPos, dir));
     }
 }
Beispiel #12
0
 /// <summary>
 /// Returns true if the face of the voxel at the given position is solid
 /// </summary>
 /// <param name="lX">The local x coordinate</param>
 /// <param name="lY">The local y coordinate</param>
 /// <param name="lY">The local z coordinate</param>
 /// <param name="dir">The direction of the face</param>
 /// <returns></returns>
 public bool IsSolid(int lX, int lY, int lZ, OrdinalDirections dir)
 {
     if (IsInChunk(lX, lY, lZ))
     {
         return(voxels[lX, lY, lZ].IsSolid(dir));
     }
     else
     {
         return(VoxelObject.IsSolid(VoxelObject.PosHelper.ChunkToObjectPosition(ChunkPosition) + new IntVector3(lX, lY, lZ), dir));
     }
 }
Beispiel #13
0
    float CalcNearestZ(VoxelObject voxel_obj)
    {
        float src_local_size = voxel_obj.Scale * 0.5f;
        int   octree_size    = (1 << voxel_obj.octree.MaxDepth);

        if (voxel_obj.UseOctreeSize)
        {
            src_local_size *= octree_size;
        }

        Vector3 offset = (voxel_obj.octree.bounds.center * (1f / octree_size)) * 2f;

        if (!OffsetByBounds)
        {
            offset = Vector3.zero;
        }

        var bounds_scales = voxel_obj.octree.bounds.extents * (1f / octree_size) * 2f * src_local_size;

        float nearest_z     = 0;
        bool  z_initialized = false;

        var obj_matrix  = voxel_obj.transform.localToWorldMatrix;
        var look_matrix = tfm.worldToLocalMatrix;

        for (int z = -1; z <= 1; z += 2)
        {
            for (int y = -1; y <= 1; y += 2)
            {
                for (int x = -1; x <= 1; x += 2)
                {
                    //var p = ((new Vector3(x, y, z)) - offset) * src_local_size;
                    var p = Vector3.Scale(new Vector3(x, y, z), bounds_scales);
                    p = obj_matrix.MultiplyPoint3x4(p);
                    var look_p = look_matrix.MultiplyPoint3x4(p);
                    if (z_initialized)
                    {
                        nearest_z = Mathf.Min(nearest_z, look_p.z);
                    }
                    else
                    {
                        nearest_z     = look_p.z;
                        z_initialized = true;
                    }
                }
            }
        }

        nearest_z = Mathf.Abs(nearest_z);

        return(nearest_z);
    }
Beispiel #14
0
 public static bool Save(string path, VoxelObject vo)
 {
     try
     {
         using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create, FileAccess.Write)))
         {
             IVoxelObjectFileIO io = new VoxelObjectFileIOV1();
             return(io.Save(vo, writer));
         }
     }
     catch (Exception)
     {
         vo = null;
         return(false);
     }
 }
Beispiel #15
0
    public static VoxelDebris NewDebris(VoxelDebris source, VoxelObject sourceData, Voxel voxel, float lifeTime, Vector3 position, Quaternion rotation)
    {
        VoxelDebris debris = ObjectPooler.Main.GetObject(source.gameObject, position, rotation).GetComponent <VoxelDebris>();

        debris.m_Tracker            = 0.0f;
        debris.m_Lifetime           = lifeTime;
        debris.m_Scale              = sourceData.m_Scale;
        debris.transform.localScale = Vector3.one * sourceData.m_Scale;

        if (debris.m_Body != null)
        {
            debris.m_Body.velocity = Vector3.zero;
        }

        return(debris);
    }
        Mesh PrepareVO(VoxelObject vo, RenderPass pass)
        {
            Mesh mesh = pass.HasFlag(RenderPass.Alpha) ? vo.AlphaMesh : vo.Mesh;

            if (mesh == null && pass.HasFlag(RenderPass.Normal))
            {
                throw new InvalidOperationException("Attempted to render null opaque mesh!");
            }

            if (mesh != null)
            {
                Master.PrepareMesh(mesh, pass);
            }

            return(mesh);
        }
            public Pattern(VoxelObject vo)
            {
                Instructions = new List <PatternInstruction>();
                ushort currentCount = 0;
                bool   skiping      = false;

                for (int x = 0; x < vo.Width; x++)
                {
                    for (int y = 0; y < vo.Height; y++)
                    {
                        for (int z = 0; z < vo.Depth; z++)
                        {
                            Block type = vo.Blocks[z, y, x];
                            if (type == Block.AIR && !skiping)
                            {
                                if (currentCount > 0)
                                {
                                    PatternInstruction inst = new PatternInstruction(false, currentCount);
                                    Instructions.Add(inst);
                                }

                                currentCount = 0;
                                skiping      = true;
                            }
                            else if (type == Block.STONE && skiping)
                            {
                                if (currentCount > 0)
                                {
                                    PatternInstruction inst = new PatternInstruction(true, currentCount);
                                    Instructions.Add(inst);
                                }

                                currentCount = 0;
                                skiping      = false;
                            }

                            currentCount++;
                        }
                    }
                }

                if (currentCount > 0)
                {
                    PatternInstruction inst = new PatternInstruction(skiping, currentCount);
                    Instructions.Add(inst);
                }
            }
Beispiel #18
0
        public CommandPostObject(Vector3 position)
            : base(position)
        {
            if (redCommandPost == null)
            {
                redCommandPost  = AssetManager.LoadVoxelObject("Models/commandpost-red.aosm", BufferUsageHint.StaticDraw);
                blueCommandPost = AssetManager.LoadVoxelObject("Models/commandpost-blue.aosm", BufferUsageHint.StaticDraw);
                commandpostTex  = GLoader.LoadTexture("Textures/Gui/commandpost.png");
            }

            Icon.Size   = new Vector2(16, 16);
            Icon.Offset = redCommandPost.UnitSize / 2f;
            Icon.Image  = new Image(commandpostTex);

            Team       = Team.A;
            EditorName = "Command Post";
        }
Beispiel #19
0
 public void AddVoxelObject(VoxelObject voxel_obj)
 {
     voxel_objs.Add(voxel_obj);
     if ((voxel_obj.octree == null) && voxel_obj.octree_data)
     {
         VoxelObject.Octree octree;
         if (octree_datas.TryGetValue(voxel_obj.octree_data, out octree))
         {
             voxel_obj.octree = octree;
         }
         else
         {
             octree = voxel_obj.ReadOctree();
             octree_datas.Add(voxel_obj.octree_data, octree);
         }
     }
 }
Beispiel #20
0
        public IntelObject(Vector3 position)
            : base(position)
        {
            if (redIntel == null)
            {
                redIntel  = AssetManager.LoadVoxelObject("Models/intel-red.aosm", BufferUsageHint.StaticDraw);
                blueIntel = AssetManager.LoadVoxelObject("Models/intel-blue.aosm", BufferUsageHint.StaticDraw);
                intelTex  = GLoader.LoadTexture("Textures/Gui/intel.png");
            }

            Icon.Size   = new Vector2(16, 16);
            Icon.Offset = redIntel.UnitSize / 2f;
            Icon.Image  = new Image(intelTex);

            Team       = Team.A;
            EditorName = "Intel";
        }
            public ColorData(VoxelObject vo)
            {
                Colors = new List <Color>();

                for (int x = 0; x < vo.Width; x++)
                {
                    for (int y = 0; y < vo.Height; y++)
                    {
                        for (int z = 0; z < vo.Depth; z++)
                        {
                            if (vo.Blocks[z, y, x] != Block.AIR)
                            {
                                Colors.Add(vo.Blocks[z, y, x].GetColor());
                            }
                        }
                    }
                }
            }
        public void LoadModel(string name)
        {
            VoxelObject tmpObj = null;

            if (VoxelIO.Load(name, out tmpObj))
            {
                Model = new VoxelEditorObject(tmpObj);
                Window.UpdateTitle(name);
                CurrentFile = name;

                if (voxelGrid != null)
                {
                    voxelGrid.Dispose();
                }

                voxelGrid = new VoxelGridObject(Model);
                Camera.Active.SetTarget(Model.CenterPosition);
            }
        }
        public bool Save(VoxelObject vo, BinaryWriter writer)
        {
            writer.Write("Generic Voxel Object");
            writer.Write(1.0f);

            writer.Write((ushort)vo.Width);
            writer.Write((ushort)vo.Height);
            writer.Write((ushort)vo.Depth);
            writer.Write(vo.CubeSize);

            Pattern pattern = new Pattern(vo);

            pattern.Write(writer);

            ColorData colors = new ColorData(vo);

            colors.Write(writer);

            return(true);
        }
        public bool Load(BinaryReader reader, out VoxelObject vo)
        {
            int   width    = (int)reader.ReadUInt16();
            int   height   = (int)reader.ReadUInt16();
            int   depth    = (int)reader.ReadUInt16();
            float cubeSize = reader.ReadSingle();

            Pattern   pattern = new Pattern(reader);
            ColorData colors  = new ColorData(reader);

            vo = new VoxelObject(cubeSize);
            vo.InitBlocks(width, height, depth);

            int patternI = 0, patternCountFollowed = 0, colorI = 0;
            PatternInstruction inst = pattern.Instructions[patternI++];

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        if (patternCountFollowed == inst.Count)
                        {
                            patternCountFollowed = 0;
                            inst = pattern.Instructions[patternI++];
                        }

                        if (!inst.Skip)
                        {
                            Color color = colors.Colors[colorI++];
                            vo.Blocks[z, y, x] = new Block(Block.STONE.Material, color.R, color.G, color.B);
                        }

                        patternCountFollowed++;
                    }
                }
            }

            return(true);
        }
    public VoxelComponent Initialize(VoxelObjectType _type = VoxelObjectType.GENERIC)
    {
        if (entity == Unity.Entities.Entity.Null)
        {
            CreateEntity();
            this.GetComponent <EntityTracker>().SetReceivedEntity(entity);
        }

        foreach (Transform child in transform)
        {
            Destroy(child.gameObject);
        }

        type = _type;
        switch (type)
        {
        case VoxelObjectType.GENERIC:
            voxelObject = new VoxelObject(sizeX, sizeY, sizeZ, this);
            break;

        case VoxelObjectType.ASTEROID:
            voxelObject = new Asteroid(sizeX, sizeY, sizeZ, this);
            break;

        case VoxelObjectType.PLANETOID:
            voxelObject = new Planetoid(sizeX, sizeY, sizeZ, this);
            break;
        }

        voxelObject.isStatic = isStatic;
        voxelObject.setName(gameObject.name);

        if (seedFromName == false)
        {
            voxelObject.setRandomSeed(voxelObject.getGUID().GetHashCode());
        }

        chunkObjects    = new GameObject[sizeX, sizeY, sizeZ];
        chunkComponents = new ChunkComponent[sizeX, sizeY, sizeZ];

        pivotPoint  = new Vector3(sizeX * Constants.CHUNK_SIZE, sizeY * Constants.CHUNK_SIZE, sizeZ * Constants.CHUNK_SIZE) * 0.5f;
        pivotPoint += (Vector3.one * 0.5f);
        pivotPoint *= -1;

        for (int x = 0; x < sizeX; x++)
        {
            for (int z = 0; z < sizeZ; z++)
            {
                for (int y = sizeY - 1; y >= 0; y--)
                {
                    ChunkComponent chunkComponent = new ChunkComponent();
                    chunkComponent.transform      = this.transform;
                    chunkComponent.position       = new Coord3D(x, y, z, voxelObject);
                    chunkComponent.voxelComponent = this;
                    chunkComponents[x, y, z]      = chunkComponent;

                    ChunkLoader.instance.Queue(chunkComponent);
                }
            }
        }

        reinitialize = false;
        initialized  = true;
        return(this);
    }
 protected void SetVoxelObject(VoxelObject vo)
 {
     renderComponent.VoxelObject = vo;
     size         = vo.UnitSize;
     halfCubeSize = new Vector3(vo.CubeSize / 2f);
 }
        void OnGUI()
        {
            var activeObject = Selection.activeGameObject;

            if (activeObject == null)
            {
                return;
            }

            _voxelObject = activeObject.GetComponent <VoxelObject>();
            if (_voxelObject == null)
            {
                return;
            }

            /*
             * var obj = EditorGUILayout.ObjectField(_voxelObject, typeof(VoxelObject),
             *  allowSceneObjects: true);
             *
             * if (obj != null)
             *  _voxelObject = obj as VoxelObject;*/


            _offsetPos = EditorGUILayout.Vector2IntField("View", _offsetPos);
            _y         = EditorGUILayout.IntSlider("Y", _y, 0, 10);

            if (_voxelObject == null)
            {
                return;
            }

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.BeginScrollView(_scrollPosition);
            for (var z = 0; z < 20; z++)
            {
                for (var x = 0; x < 20; x++)
                {
                    var voxelPos = new Vector3Int(x - _offsetPos.x, _y, 20 - z - _offsetPos.y);
                    var isVoxel  = _voxelObject.Volume.HasVoxelAt(voxelPos);
                    var isPivot  = voxelPos == _voxelObject.Volume.Pivot;
                    var style    = isVoxel ? FilledVoxel : EmptyVoxel;
                    if (isPivot && isVoxel)
                    {
                        style = PivotFilledVoxel;
                    }
                    if (isPivot && !isVoxel)
                    {
                        style = PivotEmptyVoxel;
                    }


                    if (GUI.Button(new Rect(x * CellSize + x, z * CellSize + z, CellSize, CellSize), GUIContent.none, style))
                    {
                        if (isVoxel)
                        {
                            _voxelObject.Volume.RemoveAt(voxelPos);
                        }
                        else
                        {
                            _voxelObject.Volume.SetAt(voxelPos, new VoxelData());
                        }
                    }
                }
            }
            EditorGUILayout.EndScrollView();
            if (EditorGUI.EndChangeCheck())
            {
                EditorUtility.SetDirty(_voxelObject);
                //UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
                UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
                //AssetDatabase.SaveAssets();
            }
        }
Beispiel #28
0
    void RenderVoxelObj(VoxelObject voxel_obj)
    {
        if (!voxel_obj)
        {
            return;
        }
        if (voxel_obj.octree == null)
        {
            return;
        }
        if (!(voxel_obj.enabled && voxel_obj.gameObject.activeInHierarchy))
        {
            return;
        }

        bool ortho = cam.orthographic;

        Vector4 offset_scale;
        Bounds  screen_bounds;        // not clipped to camera render borders
        float   local_size = CalcVertices(voxel_obj, out screen_bounds, out offset_scale);

        float x0, y0, z, rx, ry;

        if (ortho)
        {
            Vector3 projected_pos = cam.WorldToScreenPoint(voxel_obj.transform.position);
            float   projected_size = 0;
            float   dpx = 0, dpy = 0;           // NOT the same as screen_bounds!
            for (int i = 0; i < 8; i++)
            {
                var csi = cells_order[i];
                csi.delta      = (csi.projected - projected_pos);
                projected_size = Mathf.Max(projected_size, csi.delta.magnitude);
                dpx            = Mathf.Max(dpx, Mathf.Abs(csi.delta.x));
                dpy            = Mathf.Max(dpy, Mathf.Abs(csi.delta.y));
                cells_order[i] = csi;
            }

            rx = dpx;
            ry = dpy;
            x0 = projected_pos.x;
            y0 = projected_pos.y;
            z  = projected_pos.z;
        }
        else
        {
            Vector3 local_pos = tfm.InverseTransformPoint(voxel_obj.transform.position);
            for (int i = 0; i < 8; i++)
            {
                var csi = cells_order[i];
                csi.delta      = (csi.position_local - local_pos);
                cells_order[i] = csi;
            }

            rx = local_size;
            ry = local_size;
            x0 = local_pos.x;
            y0 = local_pos.y;
            z  = local_pos.z;
        }

        radiuses[0] = new Vector4(rx - 0.5f, ry - 0.5f, Mathf.Max(rx, ry), local_size);

        var idxyz = linked_idxyz[0];

        for (int i = 0; i < 8; i++)
        {
            var csi = cells_order[i];
            idxyz.index = csi.index;
            idxyz.dx    = csi.delta.x * 0.5f;
            idxyz.dy    = csi.delta.y * 0.5f;
            idxyz.dz    = csi.delta.z * 0.5f;
            idxyz       = idxyz.next;
        }

        RasterizeOctree(voxel_obj.octree.root, x0, y0, z, ortho, voxel_obj.tint);
    }
Beispiel #29
0
    float CalcVertices(VoxelObject voxel_obj, out Bounds screen_bounds, out Vector4 offset_scale)
    {
        float src_local_size = voxel_obj.Scale * 0.5f;
        int   octree_size    = (1 << voxel_obj.octree.MaxDepth);

        if (voxel_obj.UseOctreeSize)
        {
            src_local_size *= octree_size;
        }

        Vector3 offset = (voxel_obj.octree.bounds.center * (1f / octree_size)) * 2f;

        if (!OffsetByBounds)
        {
            offset = Vector3.zero;
        }

        offset_scale = new Vector4(offset.x, offset.y, offset.z, src_local_size);

        float local_size   = 0;       // radius of encircling sphere
        var   obj_pos      = voxel_obj.transform.position;
        var   obj_matrix   = voxel_obj.transform.localToWorldMatrix;
        var   look_matrix  = tfm.worldToLocalMatrix;
        var   look_dir     = tfm.forward;
        var   look_pos     = tfm.position;
        var   look_obj_pos = look_matrix.MultiplyPoint3x4(obj_pos);

        float z_epsilon = Mathf.Min(0.001f, cam.nearClipPlane);

        bool bounds_initialized = false;

        screen_bounds = default(Bounds);

        var bounds_scales = voxel_obj.octree.bounds.extents * (1f / octree_size) * 2f * src_local_size;

        int i = 0;

        for (int z = -1; z <= 1; z += 2)
        {
            for (int y = -1; y <= 1; y += 2)
            {
                for (int x = -1; x <= 1; x += 2)
                {
                    var p = ((new Vector3(x, y, z)) - offset) * src_local_size;
                    p = obj_matrix.MultiplyPoint3x4(p);

                    var look_p = look_matrix.MultiplyPoint3x4(p);
                    local_size = Mathf.Max(local_size, (look_obj_pos - look_p).magnitude);

                    var proj = cam.WorldToScreenPoint(p);
                    proj.z = look_p.z;

                    var csi = new CellSortInfo(i, proj.z, p, look_p, proj);
                    if (OffsetByBounds)
                    {
                        csi.position_bounds = obj_matrix.MultiplyPoint3x4(
                            Vector3.Scale(new Vector3(x, y, z), bounds_scales));
                    }
                    else
                    {
                        csi.position_bounds = p;
                    }
                    cells_order[i] = csi;

                    look_p.z = Mathf.Max(look_p.z, z_epsilon);
                    p        = tfm.TransformPoint(look_p);
                    proj     = cam.WorldToScreenPoint(p);
                    proj.z   = look_p.z;
                    if (bounds_initialized)
                    {
                        screen_bounds.Encapsulate(proj);
                    }
                    else
                    {
                        screen_bounds      = new Bounds(proj, Vector3.zero);
                        bounds_initialized = true;
                    }

                    i += 1;
                }
            }
        }

        if (DrawBounds)
        {
            DrawCubeWire();
        }

        System.Array.Sort(cells_order, delegate(CellSortInfo csi1, CellSortInfo csi2) {
            return(csi1.distance.CompareTo(csi2.distance));
        });

        return(local_size);
    }
        void RenderList(Shader shader, RenderPass pass, List <VoxelRenderComponent> list, VoxelObject commonVO = null)
        {
            // Pre-load mesh
            Mesh mesh = null;

            if (commonVO != null)
            {
                mesh = PrepareVO(commonVO, pass);
                if (mesh == null)
                {
                    return;
                }
            }

            // Go through batch
            foreach (VoxelRenderComponent vrc in list)
            {
                if (vrc.OnlyRenderFor.HasValue && !vrc.OnlyRenderFor.Value.HasFlag(pass))
                {
                    continue;
                }

                // Load mesh if were not using a common vo
                if (commonVO == null)
                {
                    mesh = PrepareVO(vrc.VoxelObject, pass);
                    if (mesh == null)
                    {
                        continue;
                    }
                }

                // Load the world matrix
                shader.LoadMatrix4("transformationMatrix", vrc.WorldMatrix);

                // Prepare the entity
                StateManager.ToggleWireframe(vrc.RenderAsWireframe);

                if (!pass.HasFlag(RenderPass.Shadow))
                {
                    shader.LoadBool("skipLight", vrc.ApplyNoLighting);
                    shader.LoadColor4("colorOverlay", vrc.ColorOverlay);
                    shader.LoadFloat("entityLighting", vrc.Lighting);
                }

                // Render the entity
                GL.DrawElements(mesh.BeginMode, mesh.VertexCount, DrawElementsType.UnsignedInt, IntPtr.Zero);

                // If we're not using a common vo, end it's mesh
                if (commonVO == null)
                {
                    Master.EndMesh();
                }
            }

            // If we are using a common vo, end it's mesh last
            if (commonVO != null)
            {
                Master.EndMesh();
            }
        }