예제 #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 RayCastRestult rayCast(Vector3 startPos, Vector3 dir, float length)
        {
            RayCastRestult outResult;
            //求局部坐标,左下角为(0,0,0),单位长度为chunkSize
            Vector3        localStartPos = startPos - new Vector3(curStartChunkX, curStartChunkY, curStartChunkZ);
            RayTraceResult rlt           = RayTrace.rayTrace(localStartPos, dir, this, length);//进行粗糙范围射线追踪

            outResult.bHit = rlt.bHit;
            if (rlt.hitLength > length)
            {
                outResult.bHit = false;
            }
            outResult.hitFaceIndex = (int)rlt.faceIndex;
            outResult.hitLength    = rlt.hitLength;
            return(outResult);
        }
예제 #3
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;
                    }
                }
            }
        }