예제 #1
0
        public static RayTraceResult rayTrace(Vector3 startPos, Vector3 dir, RayTraceChunkManager rtm, float length)
        {
            DirInfo dirInfo       = new DirInfo(dir);
            Vector3 startPosInner = startPos;
            float   hitTime       = 0;
            float   startOffset   = 0;
            bool    bHitBounds    = true;//能击中总区域,或者在内部

            if (startPos.x >= 0 && startPos.x < rtm.getSizeX() && startPos.y >= 0 && startPos.y < rtm.getSizeY() && startPos.z >= 0 && startPos.z < rtm.getSizeZ())
            {
                bHitBounds = true;
            }
            else
            {
                bHitBounds = Misc.rayHitAABB(startPos, dir, new Vector3(0, 0, 0), rtm.getSize(), ref hitTime);
                if (hitTime > 0)
                {
                    startOffset = hitTime;
                }
                startPosInner = startPos + dir * startOffset - dir * 0.01f;
            }
            if (bHitBounds)
            {
                RayTraceResult rlt = rayTraceSmall(startPosInner, dirInfo, rtm, Face.FNI_Unknown, length - startOffset);
                rlt.hitLength += startOffset;
                return(rlt);
            }
            else
            {
                return(new RayTraceResult(false, 0, 0, 0, Face.FNI_Unknown, 0));
            }
        }
예제 #2
0
        public static Color[] ToColorsA(RayTraceChunkManager rtc, int bits)
        {
            int dcx = rtc.getChunkSize().x;
            int dcy = rtc.getChunkSize().y;
            int dcz = rtc.getChunkSize().z;
            int dgx = rtc.getSizeX();
            int dgy = rtc.getSizeY();
            int dgz = rtc.getSizeZ();

            Color[,,] colors = new Color[dgx, (dgy / bits), dgz];
            for (int cx = 0; cx < dcx; cx++)
            {
                for (int cy = 0; cy < dcy; cy++)
                {
                    for (int cz = 0; cz < dcz; cz++)
                    {
                        RayTraceChunk chunk = rtc.getChunk(cx, cy, cz);
                        for (int bx = 0; bx < Const.ChunkSize; bx++)
                        {
                            for (int by = 0; by < Const.ChunkSize / bits; by++)
                            {
                                for (int bz = 0; bz < Const.ChunkSize; bz++)
                                {
                                    int iv = 0;
                                    for (int n = 0; n < bits; n++)
                                    {
                                        iv |= chunk.testBlock(bx, by * bits + n, bz) ? (1 << n) : 0;
                                    }
                                    float a  = iv / (float)((1 << bits) - 1);
                                    int   gx = cx * Const.ChunkSize + bx;
                                    int   gy = cy * Const.ChunkSize / bits + by;
                                    int   gz = cz * Const.ChunkSize + bz;
                                    colors[gx, gy, gz] = new Color(0, 0, 0, a);
                                }
                            }
                        }
                    }
                }
            }

            int sizeX = colors.GetLength(0);
            int sizeY = colors.GetLength(1);
            int sizeZ = colors.GetLength(2);

            Color[] rlt = new Color[sizeX * sizeY * sizeZ];
            for (int x = 0; x < sizeX; x++)
            {
                for (int y = 0; y < sizeY; y++)
                {
                    for (int z = 0; z < sizeZ; z++)
                    {
                        rlt[z * sizeY * sizeX + y * sizeX + x] = colors[x, y, z];
                    }
                }
            }
            return(rlt);
        }
예제 #3
0
        private static Texture3D Create3DTexture(RayTraceChunkManager rtc)
        {
            Texture3D voxelTexture = new Texture3D(rtc.getSizeX(), rtc.getSizeY() / 8, rtc.getSizeZ(), TextureFormat.Alpha8, false);

            voxelTexture.filterMode = FilterMode.Point;
            voxelTexture.wrapMode   = TextureWrapMode.Clamp;
            voxelTexture.SetPixels(ToColorsA(rtc, 8));
            voxelTexture.Apply();
            return(voxelTexture);
        }
예제 #4
0
 public void Init(RayTraceChunkManager rtc)
 {
     constValueTexture = CreateConstValueTexture();
     texVoxel3D        = Create3DTexture(rtc);
     calcAoMaterial    = new Material(Shader.Find("Hidden/RaytraceAo"));
 }
예제 #5
0
        public static RayTraceResult rayTraceSmall(Vector3 startPos, DirInfo dirInfo, RayTraceChunkManager rtm, Face faceIn, float maxLength)
        {
            int   X        = (int)(startPos.x + dirInfo.stepX * 0.0001f);
            int   Y        = (int)(startPos.y + dirInfo.stepY * 0.0001f);
            int   Z        = (int)(startPos.z + dirInfo.stepZ * 0.0001f);
            float tMaxX    = (dirInfo.stepX > 0 ? (1 - (startPos.x - X)) : (startPos.x - X)) * dirInfo.tDeltaX;//沿射线走多远才能跳到下一个X格
            float tMaxY    = (dirInfo.stepY > 0 ? (1 - (startPos.y - Y)) : (startPos.y - Y)) * dirInfo.tDeltaY;
            float tMaxZ    = (dirInfo.stepZ > 0 ? (1 - (startPos.z - Z)) : (startPos.z - Z)) * dirInfo.tDeltaZ;
            int   outSizeX = dirInfo.stepX > 0 ? rtm.getSizeX() : -1;
            int   outSizeY = dirInfo.stepY > 0 ? rtm.getSizeY() : -1;
            int   outSizeZ = dirInfo.stepZ > 0 ? rtm.getSizeZ() : -1;

            while (true)
            {
                if (tMaxX < tMaxY)
                {
                    if (tMaxX < tMaxZ)
                    {
                        X += dirInfo.stepX;
                        if (X == outSizeX)
                        {
                            return(new RayTraceResult(false, X, Y, Z, dirInfo.stepX > 0 ? Face.FNI_x0 : Face.FNI_x1, tMaxX));
                        }
                        else
                        {
                            if (tMaxX > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxX));
                            }
                            else if (rtm.testBlock(X, Y, Z))
                            {
                                return(new RayTraceResult(true, X, Y, Z, dirInfo.stepX > 0 ? Face.FNI_x0 : Face.FNI_x1, tMaxX));
                            }
                        }
                        tMaxX += dirInfo.tDeltaX;
                    }
                    else
                    {
                        Z += dirInfo.stepZ;
                        if (Z == outSizeZ)
                        {
                            return(new RayTraceResult(false, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                        }
                        else
                        {
                            if (tMaxZ > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxZ));
                            }
                            else if (rtm.testBlock(X, Y, Z))
                            {
                                return(new RayTraceResult(true, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                            }
                        }
                        tMaxZ += dirInfo.tDeltaZ;
                    }
                }
                else
                {
                    if (tMaxY < tMaxZ)
                    {
                        Y += dirInfo.stepY;
                        if (Y == outSizeY)
                        {
                            return(new RayTraceResult(false, X, Y, Z, dirInfo.stepY > 0 ? Face.FNI_y0 : Face.FNI_y1, tMaxY));
                        }
                        else
                        {
                            if (tMaxY > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxY));
                            }
                            else if (rtm.testBlock(X, Y, Z))
                            {
                                return(new RayTraceResult(true, X, Y, Z, dirInfo.stepY > 0 ? Face.FNI_y0 : Face.FNI_y1, tMaxY));
                            }
                        }

                        tMaxY += dirInfo.tDeltaY;
                    }
                    else
                    {
                        Z += dirInfo.stepZ;
                        if (Z == outSizeZ)
                        {
                            return(new RayTraceResult(false, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                        }
                        else
                        {
                            if (tMaxZ > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxZ));
                            }
                            else if (rtm.testBlock(X, Y, Z))
                            {
                                return(new RayTraceResult(true, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                            }
                        }

                        tMaxZ += dirInfo.tDeltaZ;
                    }
                }
            }
        }
예제 #6
0
        public static RayTraceResult rayTraceBig(Vector3 startPos, DirInfo dirInfo, RayTraceChunkManager rtm, Face faceIn, float maxLength)
        {
            int S  = rtm.ChunkSize;
            int CX = (int)(startPos.x + dirInfo.stepX * 0.0001f) / S;
            int CY = (int)(startPos.y + dirInfo.stepY * 0.0001f) / S;
            int CZ = (int)(startPos.z + dirInfo.stepZ * 0.0001f) / S;

            int X = CX * S;
            int Y = CY * S;
            int Z = CZ * S;

            float curDistance = 0;

            float tMaxX = (dirInfo.stepX > 0 ? (S - (startPos.x - X)) : (startPos.x - X)) * dirInfo.tDeltaX;//沿射线走多远才能跳到下一个X格
            float tMaxY = (dirInfo.stepY > 0 ? (S - (startPos.y - Y)) : (startPos.y - Y)) * dirInfo.tDeltaY;
            float tMaxZ = (dirInfo.stepZ > 0 ? (S - (startPos.z - Z)) : (startPos.z - Z)) * dirInfo.tDeltaZ;


            int outSizeCX = dirInfo.stepX > 0 ? rtm.getSizeX() / S : -1;
            int outSizeCY = dirInfo.stepY > 0 ? rtm.getSizeY() / S : -1;
            int outSizeCZ = dirInfo.stepZ > 0 ? rtm.getSizeZ() / S : -1;

            while (true)
            {
                if (tMaxX < tMaxY)
                {
                    if (tMaxX < tMaxZ)
                    {
                        if (!rtm.isChunkEmpty(CX, CY, CZ))
                        {
                            RayTraceResult smallRlt = rayTraceSmall(startPos + dirInfo.dir * curDistance, dirInfo, rtm, faceIn, Mathf.Max(tMaxX, maxLength) - curDistance);
                            if (smallRlt.bHit)
                            {
                                smallRlt.hitLength += curDistance;
                                return(smallRlt);
                            }
                        }

                        CX += dirInfo.stepX;
                        if (CX == outSizeCX)
                        {
                            return(new RayTraceResult(false, X, Y, Z, dirInfo.stepX > 0 ? Face.FNI_x0 : Face.FNI_x1, tMaxX));
                        }
                        else
                        {
                            if (tMaxX > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxX));
                            }
                        }
                        curDistance = tMaxX;
                        tMaxX      += dirInfo.tDeltaX * S;
                    }
                    else
                    {
                        if (!rtm.isChunkEmpty(CX, CY, CZ))
                        {
                            RayTraceResult smallRlt = rayTraceSmall(startPos + dirInfo.dir * curDistance, dirInfo, rtm, faceIn, Mathf.Max(tMaxZ, maxLength) - curDistance);
                            if (smallRlt.bHit)
                            {
                                smallRlt.hitLength += curDistance;
                                return(smallRlt);
                            }
                        }

                        CZ += dirInfo.stepZ;
                        if (CZ == outSizeCZ)
                        {
                            return(new RayTraceResult(false, X, Y, Z, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                        }
                        else
                        {
                            if (tMaxZ > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxZ));
                            }
                        }
                        curDistance = tMaxZ;
                        tMaxZ      += dirInfo.tDeltaZ * S;
                    }
                }
                else
                {
                    if (tMaxY < tMaxZ)
                    {
                        if (!rtm.isChunkEmpty(CX, CY, CZ))
                        {
                            RayTraceResult smallRlt = rayTraceSmall(startPos + dirInfo.dir * curDistance, dirInfo, rtm, faceIn, Mathf.Max(tMaxY, maxLength) - curDistance);
                            if (smallRlt.bHit)
                            {
                                smallRlt.hitLength += curDistance;
                                return(smallRlt);
                            }
                        }

                        CY += dirInfo.stepY;
                        if (CY == outSizeCY)
                        {
                            return(new RayTraceResult(false, X, Y, Z, dirInfo.stepY > 0 ? Face.FNI_y0 : Face.FNI_y1, tMaxY));
                        }
                        else
                        {
                            if (tMaxY > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxY));
                            }
                        }

                        curDistance = tMaxY;
                        tMaxY      += dirInfo.tDeltaY * S;
                    }
                    else
                    {
                        if (!rtm.isChunkEmpty(CX, CY, CZ))
                        {
                            RayTraceResult smallRlt = rayTraceSmall(startPos + dirInfo.dir * curDistance, dirInfo, rtm, faceIn, Mathf.Max(tMaxZ, maxLength) - curDistance);
                            if (smallRlt.bHit)
                            {
                                smallRlt.hitLength += curDistance;
                                return(smallRlt);
                            }
                        }

                        CZ += dirInfo.stepZ;
                        if (CZ == outSizeCZ)
                        {
                            return(new RayTraceResult(false, X, Y, X, dirInfo.stepZ > 0 ? Face.FNI_z0 : Face.FNI_z1, tMaxZ));
                        }
                        else
                        {
                            if (tMaxZ > maxLength)
                            {
                                return(new RayTraceResult(false, X, Y, Z, Face.FNI_OutOfLength, tMaxZ));
                            }
                        }

                        curDistance = tMaxZ;
                        tMaxZ      += dirInfo.tDeltaZ * S;
                    }
                }
            }
        }