コード例 #1
0
        /// <summary>
        /// Done while BuildVBO generating (position in AOArray)
        /// </summary>
        void GenCubeShadowLightAO(SmallCube _cube, int _cx, int _cy, int _cz, int _aox, int _aoy, int _aoz, byte _byVFMask, ref Color[] _colors)
        {
            int i, j;

            Color gradCol = m_colPalette[_cube.byMatL0 - 1];

            //Lighting to face
            for (i = 0; i < 6; i++) //6 faces
            {
                if ((_byVFMask & (1 << i)) == 0)
                {
                    continue; //Face invisible
                }
                for (j = 0; j < 4; j++)
                {
                    int nNumVertex = CubeHelpers.fv[i, j];  //Face,Corner

                    byte byOcclusion = SmoothOcclusion(_cube, _aox, _aoy, _aoz, nNumVertex, i);

                    m_shadowVerts[j] = Color.Lerp(gradCol, Color.Black, (float)byOcclusion / 6.0f);
                }


                int k = i << 2;//*4

                _colors[k]     = m_shadowVerts[0];
                _colors[k + 1] = m_shadowVerts[1];
                _colors[k + 2] = m_shadowVerts[2];
                _colors[k + 3] = m_shadowVerts[3];
            }
        }
コード例 #2
0
        public byte CalcVisibleFaces(SmallCube c, int cx, int cy, int cz)
        {
            byte byVFMask = 0x00;  //By default no faces visibles

            if (c.byMatL0 == 0)
            {
                return(byVFMask);
            }

            //For each Cube's faces
            SmallCube nc;
            int       i;

            for (i = 0; i < 6; i++) //6 faces
            {
                bool bvis = true;

                //check if neighbour face is solid
                m_array.GetNeighbourCube(cx, cy, cz, (CubeHelpers.SIDE)i, out nc);

                if (nc.byMatL0 != 0)
                {
                    bvis = false;
                }

                //Update visible face
                if (bvis)
                {
                    byVFMask |= (byte)(1 << i);
                }
            }

            return(byVFMask);
        }
コード例 #3
0
        public CubeBrush(Game _game, int _sizeX, int _sizeY, int _sizeZ, bool _createDummy)
        {
            Game = _game;

            //Array size
            SetSize(_sizeX, _sizeY, _sizeZ);

            //Create a plane at bottom
            if (_createDummy)
            {
                SmallCube cube = new SmallCube();
                cube.byMatL0 = 16;

                int x, y, z;
                y = 0;
                for (x = 0; x < _sizeX; x++)
                {
                    for (z = 0; z < _sizeZ; z++)
                    {
                        m_array.SetCube(x, y, z, cube);
                    }
                }
            }

            //Create Palette
            BuildDefaultColorPalette();

            //Meshes
            m_genMesh = new GenMesh();
        }
コード例 #4
0
        public bool GetNeighbourCube(int x, int y, int z, CubeHelpers.SIDE side, out SmallCube _c)
        {
            _c = m_emptyCube;

            switch (side)
            {
            case CubeHelpers.SIDE.O_LEFT: x -= 1; break;   //0: -x

            case CubeHelpers.SIDE.O_RIGHT: x += 1; break;  //1: +x

            case CubeHelpers.SIDE.O_BOTTOM: y -= 1; break; //2: -y

            case CubeHelpers.SIDE.O_TOP: y += 1; break;    //3: +y

            case CubeHelpers.SIDE.O_BACK: z -= 1; break;   //4: -z

            case CubeHelpers.SIDE.O_FRONT: z += 1; break;  //5: +z
            }
            if (x < 0 || y < 0 || z < 0)
            {
                return(false);
            }
            if (x >= CUBESIZEX || y >= CUBESIZEY || z >= CUBESIZEZ)
            {
                return(false);
            }

            GetCube(x, y, z, out _c);
            return(true);
        }
コード例 #5
0
        /// <summary>
        /// Get Cube vvalue at coords
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="_c"></param>
        public void GetCube(int x, int y, int z, out SmallCube _c)
        {
            //Get chunk
            int chX    = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
            int chY    = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
            int chZ    = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
            int offset = (chX * FlattenOffset) + (chZ * CHUNKSIZEY) + chY;

            CubeChunk3D chunk = m_arrayChunks[offset];

            if (chunk == null)
            {
                _c = m_emptyCube;
                return;
            }

            if (chunk.m_array == null)
            {
                _c = chunk.m_solidChunkCube;
                return;
            }

            //Return Cube into chunk
            chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
            chY = y - (chY << CHUNKSIZE_OPSHIFT); //(by * CHUNKSIZE);
            chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //(bz * CHUNKSIZE);

            offset = (chX << FlattenOffsetChunk_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;

            _c = chunk.m_array[offset];
        }
コード例 #6
0
        public void SetCube(int _x, int _y, int _z, SmallCube _c)
        {
            if (m_array == null)
            {
                m_array = new SmallCube[CubeArray3D.CHUNKSIZE * CubeArray3D.CHUNKSIZE * CubeArray3D.CHUNKSIZE];
            }

            m_array[(_x << CubeArray3D.FlattenOffsetChunk_OPSHIFT) + (_z << CubeArray3D.CHUNKSIZE_OPSHIFT) + _y] = _c;
        }
コード例 #7
0
 public void GetCube(int _x, int _y, int _z, out SmallCube _c)
 {
     if (m_array == null)
     {
         _c = m_solidChunkCube;
     }
     else
     {
         _c = m_array[(_x << CubeArray3D.FlattenOffsetChunk_OPSHIFT) + (_z << CubeArray3D.CHUNKSIZE_OPSHIFT) + _y];
     }
 }
コード例 #8
0
        public void SetCube(int _x, int _y, int _z, SmallCube _c)
        {
            if (_x < 0 || _y < 0 || _z < 0)
            {
                return;
            }
            if (_x >= m_array.CUBESIZEX || _y >= m_array.CUBESIZEY || _z >= m_array.CUBESIZEZ)
            {
                return;
            }

            m_array.SetCube(_x, _y, _z, _c);
        }
コード例 #9
0
        /// <summary>
        /// Set Cube value at coords
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="st"></param>
        public void SetCube(int x, int y, int z, SmallCube st)
        {
            int         chX    = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
            int         chY    = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
            int         chZ    = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
            int         offset = (chX * FlattenOffset) + (chZ * CHUNKSIZEY) + chY;
            CubeChunk3D chunk  = m_arrayChunks[offset];

            if (chunk == null)
            {
                chunk = new CubeChunk3D();
                m_arrayChunks[offset] = chunk;
            }

            chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
            chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE);
            chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE);

            chunk.SetCube(chX, chY, chZ, st);
        }
コード例 #10
0
        /// <summary>
        /// Smooth occlusion per face (position in AOArray)
        /// </summary>
        byte SmoothOcclusion(SmallCube _cube, int _aox, int _aoy, int _aoz, int _vidx, int _side)
        {
            byte oc = 0;
            int  offset;

            Vector3Int o = new Vector3Int(_aox, _aoy, _aoz);

            Vector3Int r = CubeHelpers.SolidVertex[_vidx];


            int sign = _side & 1;
            int dim  = _side >> 1;

            if (sign != 0)
            {
                o[CubeHelpers.D[dim]] += 1;
            }
            else
            {
                o[CubeHelpers.D[dim]] -= 1;
            }


            //current
            int x, y, z;
            int xx, yy, zz;

            x = o[0]; y = o[1]; z = o[2];

            x = x + 1;
            y = y + 1;
            z = z + 1;

            xx = x; yy = y; zz = z;

            offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy; //3darray[(x * (sy*sz)) + (z * sy) + y]
            offset = Math.Max(0, offset);
            offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
            oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);

            if (dim == 0)//X
            {
                int s1 = 1;
                int s2 = 1;
                if (r[1] == 0)
                {
                    s1 = -s1;             //corner
                }
                if (r[2] == 0)
                {
                    s2 = -s2;             //corner
                }
                //Y-Z
                yy     = y; zz = z + s2;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);

                yy     = y + s1; zz = z;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);

                yy     = y + s1; zz = z + s2;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);
            }
            else if (dim == 1)//Y
            {
                int s1 = 1;
                int s2 = 1;
                if (r[0] == 0)
                {
                    s1 = -s1;             //corner
                }
                if (r[2] == 0)
                {
                    s2 = -s2;             //corner
                }
                //X-Z
                xx     = x; zz = z + s2;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);

                xx     = x + s1; zz = z;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);

                xx     = x + s1; zz = z + s2;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);
            }
            else if (dim == 2) //Z
            {
                int s1 = 1;
                int s2 = 1;
                if (r[0] == 0)
                {
                    s1 = -s1;             //corner
                }
                if (r[1] == 0)
                {
                    s2 = -s2;             //corner
                }
                //X-Y
                xx     = x; yy = y + s2;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);

                xx     = x + s1; yy = y;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);

                xx     = x + s1; yy = y + s2;
                offset = (xx * (FlattenOffsetAO)) + (zz * AO_CUBESIZE_Y) + yy;
                offset = Math.Max(0, offset);
                offset = Math.Min(offset, (AO_CUBESIZE_X * AO_CUBESIZE_Y * AO_CUBESIZE_Z) - 1);
                oc    += (byte)((int)m_abyOcclusionCubeMap[offset] >> 1);
            }


            return(oc);
        }
コード例 #11
0
        //Generate a cube VBO
        //.position in CubeArray3D
        void GenCubeVBO2(SmallCube _c, int _cx, int _cy, int _cz, int _x, int _y, int _z)
        {
            int i, j;

            ////////////////////////// COMPUTE VISIBLES FACES MASK
            byte byVFMask = CalcVisibleFaces(_c, _cx, _cy, _cz);

            if (byVFMask == 0)
            {
                return;
            }

            ////////////////////////// COMPUTE VERTICES POS
            int nNumVertex;

            for (j = 0; j < 8; j++)
            {
                m_bVertexComputed[j] = false;
                m_vertComputed[j]    = Vector3.Zero;
            }

            int wcx = _cx; //To World coord
            int wcy = _cy; //To World coord
            int wcz = _cz; //To World Coord


            //For each Cube's faces
            for (i = 0; i < 6; i++) //6 faces
            {
                //If face visibility precalc mask
                if ((byVFMask & (1 << i)) != 0)
                {
                    for (j = 0; j < 4; j++)                         //4 corners
                    {
                        nNumVertex = CubeHelpers.fv[i, j];          //Face,Corner

                        if (m_bVertexComputed[nNumVertex] == false) //if never calc
                        {
                            CubeHelpers.GetSolidWorldVertex(wcx, wcy, wcz, nNumVertex, out m_vertComputed[nNumVertex]);

                            m_vertComputed[nNumVertex]   *= CubeHelpers.CUBE_SIZE;     //Scale cube size
                            m_bVertexComputed[nNumVertex] = true;
                        }
                    }
                }
            }

            ////////////////////////// COMPUTE SHADOW LIGHTING
            GenCubeShadowLightAO(_c, _cx, _cy, _cz, _x, _y, _z, byVFMask, ref m_vertCols);

            ////////////////////////// COMPUTE CUBE FACES

            int v0, v1, v2, v3;
            int iv0, iv1, iv2, iv3;

            for (i = 0; i < 6; i++) //6 faces
            {
                if ((byVFMask & (1 << i)) == 0)
                {
                    continue;              //Face invisible
                }
                v0 = CubeHelpers.fv[i, 0]; //Face,Corner
                v1 = CubeHelpers.fv[i, 1]; //Face,Corner
                v2 = CubeHelpers.fv[i, 2]; //Face,Corner
                v3 = CubeHelpers.fv[i, 3]; //Face,Corner


                int dim = i >> 1; // 0,0,1,1,2,2 X,Y,Z

                j = i << 2;       //Color index in m_vertCols

                /////////////////////
                //Get face normal
                Vector3 n1 = CubeHelpers.FacesPerSideNormal[i];

                ////////////////////////////////
                //Add vertices

                //V0
                iv0 = m_genMesh.AddVertex(ref m_vertComputed[v0], ref m_vertCols[j], ref n1);

                //V1
                iv1 = m_genMesh.AddVertex(ref m_vertComputed[v1], ref m_vertCols[j + 1], ref n1);

                //V2
                iv2 = m_genMesh.AddVertex(ref m_vertComputed[v2], ref m_vertCols[j + 2], ref n1);

                //V3
                iv3 = m_genMesh.AddVertex(ref m_vertComputed[v3], ref m_vertCols[j + 3], ref n1);

                ////////////////////////////////
                //Add Face

                m_genMesh.AddQuad((ushort)iv0, (ushort)iv1, (ushort)iv2, (ushort)iv3);
            }
        }
コード例 #12
0
        public bool RayCast(Vector3 _o, Vector3 _ray, float _dist, ref BoundingBox _obb, ref Vector3Int _oposcubeTrack, out SmallCube _ocube)
        {
            float cs = (float)CubeHelpers.CUBE_SIZE;

            //Step from _o to _ray
            float d = 0.0f;

            Vector3 p = _o;

            _ocube = CubeArray3D.m_emptyCube;

            //Debug.WriteLine("RayCast start at {0} dir {1}", p, _ray);

            while (d < _dist)
            {
                //Get cube at _o
                int cx = (int)(p.X / CubeHelpers.CUBE_SIZE); //World To Cube unit
                int cy = (int)(p.Y / CubeHelpers.CUBE_SIZE);
                int cz = (int)(p.Z / CubeHelpers.CUBE_SIZE);

                if (cx >= 0 && cy >= 0 && cz >= 0 &&
                    cx < m_array.CUBESIZEX && cy < m_array.CUBESIZEY && cz < m_array.CUBESIZEZ)
                {
                    SmallCube cube;
                    m_array.GetCube(cx, cy, cz, out cube);

                    if (cube.byMatL0 != 0)
                    {
                        //Debug.WriteLine("Cube Found at {0},{1},{2}", cx, cy, cz);

                        _oposcubeTrack.X = cx; //In cube unit
                        _oposcubeTrack.Y = cy; //In cube unit
                        _oposcubeTrack.Z = cz;

                        //BB
                        _obb.Min.X = (float)(cx * CubeHelpers.CUBE_SIZE); //To world coords
                        _obb.Min.Y = (float)(cy * CubeHelpers.CUBE_SIZE); //To world coords
                        _obb.Min.Z = (float)(cz * CubeHelpers.CUBE_SIZE); //To world coords

                        _obb.Max.X = _obb.Min.X + cs;
                        _obb.Max.Y = _obb.Min.Y + cs;
                        _obb.Max.Z = _obb.Min.Z + cs;

                        _ocube = cube;

                        return(true);
                    }
                }

                d += 1.0f;
                p += _ray;
            }
            //Debug.WriteLine("RayCast end at {0}", p);


            return(false);
        }
コード例 #13
0
 public void GetCube(int _x, int _y, int _z, out SmallCube _c)
 {
     m_array.GetCube(_x, _y, _z, out _c);
 }
コード例 #14
0
        /// <summary>
        /// Read .VOX File and return a CubeArray3D
        /// </summary>
        /// <param name="_strPath"></param>
        /// <returns></returns>
        //public bool ReadFile(Windows.Storage.Streams.DataReader _br)
        public bool ReadFile(BinaryReader _br)
        {
            //////////////////////////////////////////////////
            //Read Header
            //4 bytes: magic number ('V' 'O' 'X' 'space' )
            //4 bytes: version number (current version is 150 )
            UInt32 signature = _br.ReadUInt32();

            if (signature != 0x20584F56)  //56 4F 58 20
            {
                Debug.WriteLine("Not an MagicaVoxel File format");
                return(false);
            }

            UInt32 version = _br.ReadUInt32();

            if (version < 150)
            {
                Debug.WriteLine("MagicaVoxel version too old");
                return(false);
            }


            // header
            //4 bytes: chunk id
            //4 bytes: size of chunk contents (n)
            //4 bytes: total size of children chunks(m)

            //// chunk content
            //n bytes: chunk contents

            //// children chunks : m bytes
            //{ child chunk 0 }
            //{ child chunk 1 }
            int sizeX, sizeY, sizeZ;

            sizeX = sizeY = sizeZ = 0;
            int numVoxels = 0;
            int offsetX, offsetY, offsetZ;

            offsetX = offsetY = offsetZ = 0;

            SmallCube cube = new SmallCube();

#if ANDROID
            while (_br.BaseStream.IsDataAvailable())
#else
            while (_br.BaseStream.Position < _br.BaseStream.Length)
#endif
            {
                string chunkName           = new string(_br.ReadChars(4));
                UInt32 chunkSize           = _br.ReadUInt32();
                UInt32 chunkTotalChildSize = _br.ReadUInt32();


                if (chunkName == "SIZE")
                {
                    //(4 bytes x 3 : x, y, z )
                    sizeX = _br.ReadInt32();
                    sizeY = _br.ReadInt32();
                    sizeZ = _br.ReadInt32();

                    //Align size to chunk size
                    int sx = sizeX + ((CubeArray3D.CHUNKSIZE - (sizeX % CubeArray3D.CHUNKSIZE)) % CubeArray3D.CHUNKSIZE);
                    int sy = sizeY + ((CubeArray3D.CHUNKSIZE - (sizeY % CubeArray3D.CHUNKSIZE)) % CubeArray3D.CHUNKSIZE);
                    int sz = sizeZ + ((CubeArray3D.CHUNKSIZE - (sizeZ % CubeArray3D.CHUNKSIZE)) % CubeArray3D.CHUNKSIZE);

                    m_carray.SetSize(sx, sz, sy); //Reversed y-z

                    offsetX = (sx - sizeX) >> 1;
                    offsetY = (sz - sizeZ) >> 1; //Reversed y-z
                    offsetZ = (sy - sizeY) >> 1; //Reversed y-z
                }
                else if (chunkName == "XYZI")
                {
                    //(numVoxels : 4 bytes )
                    //(each voxel: 1 byte x 4 : x, y, z, colorIndex ) x numVoxels
                    numVoxels = _br.ReadInt32();
                    while (numVoxels > 0)
                    {
                        byte vx = _br.ReadByte();
                        byte vy = _br.ReadByte();
                        byte vz = _br.ReadByte();
                        byte vi = _br.ReadByte();
                        cube.byMatL0 = vi;
                        m_carray.SetCube(offsetX + vx, offsetY + vz, m_carray.CUBESIZEZ - vy - 1 - offsetZ, cube);  //Reserved y-z

                        numVoxels--;
                    }
                }
                else if (chunkName == "RGBA")
                {
                    //(each pixel: 1 byte x 4 : r, g, b, a ) x 256
                    for (int i = 0; i < 256; i++)
                    {
                        byte r = _br.ReadByte();
                        byte g = _br.ReadByte();
                        byte b = _br.ReadByte();
                        byte a = _br.ReadByte();

                        m_palette[i] = Color.FromNonPremultiplied(r, g, b, a);
                    }
                }
            }

            return(true);
        }
コード例 #15
0
        public SmallCube m_solidChunkCube; //If solid Chunk


        public CubeChunk3D()
        {
            m_solidChunkCube = CubeArray3D.m_emptyCube;
        }