예제 #1
0
        private void CalculateRenderMesh(Chunk chunk, MeshData meshData, int x1, int y1, int z1, int x2, int y2, int z2,
                                         Block bA, Block bB, BlockAttributeCalculator aBAC, BlockAttributeCalculator bBAC, int direction, bool bBInRange)
        {
            BlockRenderType aBACRenderType = aBAC.GetBlockRenderType(bA.ExtendId);

            if (aBACRenderType == BlockRenderType.Part)
            {
                //渲染(特殊)物块
                aBAC.CalculateSpecialMesh(chunk, x1, y1, z1, meshData, bA, bB, bBAC, (Direction)direction);
            }

            BlockRenderType bBACRenderType = bBAC.GetBlockRenderType(bB.ExtendId);

            if (bBACRenderType == BlockRenderType.Part)
            {
                //不能因为x2,y2,z2有可能不在chunk中 而需要保证x2,y2,z2在chunk中)
//				Chunk tempChunk = chunk;
//				if(!bBInRange)
//				{
//					int x2WorldPos = chunk.worldPos.x + x2;
//					int y2WorldPos = chunk.worldPos.y + y2;
//					int z2WorldPos = chunk.worldPos.z + z2;
//					tempChunk = chunk.world.GetChunk(x2WorldPos,y2WorldPos,z2WorldPos);
//					x2 = x2WorldPos - tempChunk.worldPos.x;
//					y2 = y2WorldPos - tempChunk.worldPos.y;
//					z2 = z2WorldPos - tempChunk.worldPos.z;
//				}
                //渲染(特殊)物块(不能确定当前坐标会在chunk中)
                bBAC.CalculateSpecialMesh(chunk, x2, y2, z2, meshData, bB, bA, aBAC, (Direction)(-direction));
            }
        }
예제 #2
0
        private void RefreshRenderMask(bool[] renderMask, Direction[] renderDirectionMask, Block[] curRenderBlocks, LightVertice[] sunLightsMask, LightVertice[] blockLightsMask,
                                       int maskIndex, Section section, int x1, int y1, int z1, int x2, int y2, int z2, Block bA, Block bB, BlockAttributeCalculator aBAC,
                                       BlockAttributeCalculator bBAC, bool bBInRange, int direction)
        {
            if (aBAC.CanCalculateMesh(bA, bB, bBAC, (Direction)(direction)))
            {
                renderMask[maskIndex]          = true;
                renderDirectionMask[maskIndex] = (Direction)(direction);
                curRenderBlocks[maskIndex]     = bA;
                sunLightsMask[maskIndex]       = GetSunLightVertice(section, x1, y1, z1, (Direction)(direction));
                blockLightsMask[maskIndex]     = GetBlockLightVertice(section, x1, y1, z1, (Direction)(direction));
//				sunLightsMask[maskIndex] = section.GetSunLight(x2,y2,z2,bBInRange);
//				blockLightsMask[maskIndex] = section.GetBlockLight(x2,y2,z2,bBInRange);
            }
            else if (bBAC.CanCalculateMesh(bB, bA, aBAC, (Direction)(-direction)))
            {
                renderMask[maskIndex]          = true;
                renderDirectionMask[maskIndex] = (Direction)(-direction);
                curRenderBlocks[maskIndex]     = bB;
//				sunLightsMask[maskIndex] = section.GetSunLight(x1,y1,z1,true);
//				blockLightsMask[maskIndex] = section.GetBlockLight(x1,y1,z1,true);
                sunLightsMask[maskIndex]   = GetSunLightVertice(section, x2, y2, z2, (Direction)(-direction));
                blockLightsMask[maskIndex] = GetBlockLightVertice(section, x2, y2, z2, (Direction)(-direction));
            }
            else
            {
                renderMask[maskIndex] = false;
            }
        }
예제 #3
0
        private void SpreadVerticalInPos(int x, int y, int z, Chunk chunk, int curLightLevel)
        {
            //光照强度小于等于1时不再传播
            if (curLightLevel < 2)
            {
                return;
            }
            //当前高度大于光照高度,不再传播
            if (y >= chunk.GetHeight(x, z, true))
            {
                SetLight(chunk, x, y, z, WorldConfig.Instance.maxLightLevel);
                return;
            }
            Block b = chunk.GetBlock(x, y, z, true);
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int lightDamp = calculator.LightDamp(b.ExtendId);

            if (lightDamp < WorldConfig.Instance.maxLightLevel)
            {
                int lightLevel = chunk.GetSunLight(x, y, z);

                int nextLightLevel = curLightLevel - lightDamp - 1;
                if (nextLightLevel > lightLevel)
                {
                    SetLight(chunk, x, y, z, nextLightLevel);
                }
            }
        }
예제 #4
0
        public void SetBlock(int x, int y, int z, Block block, bool isInRange = false)
        {
            if (!isInRange && !IsInRange(x, y, z))
            {
                chunk.SetBlock(x, chunkOffsetY + y, z, block);
            }
            else
            {
                Block b = GetRealBlock(x, y, z);
                BlockAttributeCalculator old           = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
                BlockRenderType          oldRenderType = old.GetBlockRenderType(b.ExtendId);
                if (oldRenderType != BlockRenderType.None)
                {
                    visibleBlocks--;
                }

                if (oldRenderType == BlockRenderType.Part)
                {
                    specialBlocks--;
                }
                BlockAttributeCalculator cur           = BlockAttributeCalculatorFactory.GetCalculator(block.BlockType);
                BlockRenderType          curRenderType = cur.GetBlockRenderType(block.ExtendId);
                if (curRenderType != BlockRenderType.None)
                {
                    visibleBlocks++;
                }
                if (curRenderType == BlockRenderType.Part)
                {
                    specialBlocks++;
                }
                SetRealBlock(x, y, z, block);
                chunk.isUpdate = true;
            }
        }
예제 #5
0
 public override bool CanCalculateMesh(Block self, Block other, BlockAttributeCalculator otherCalculator, Direction direction)
 {
     if (other.BlockType == BlockType.Air)
     {
         return(true);
     }
     return(false);
 }
예제 #6
0
 public virtual bool CanCalculateMesh(Block self, Block other, BlockAttributeCalculator otherCalculator, Direction direction)
 {
     if (GetBlockRenderType(self.ExtendId) == BlockRenderType.All &&
         otherCalculator.GetBlockRenderType(other.ExtendId) != BlockRenderType.All)
     {
         return(true);
     }
     return(false);
 }
예제 #7
0
        private void ShrinkHorizontalInPos(int x, int y, int z, Chunk chunk, int prevLightLevel, int curLightLevel)
        {
            //当前光照强度为最大值时不收缩
            if (curLightLevel >= WorldConfig.Instance.maxLightLevel)
            {
                return;
            }
            //当前高度大于光照高度,不再收缩,直接从旁边扩散
            if (y >= chunk.GetHeight(x, z, true))
            {
                int lightLevel = chunk.GetSunLight(x, y, z);
                int nextIndex  = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk));
                return;
            }
            Block b = chunk.GetBlock(x, y, z, true);
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int lightDamp = calculator.LightDamp(b.ExtendId);

            if (lightDamp < WorldConfig.Instance.maxLightLevel)
            {
                int lightLevel = chunk.GetSunLight(x, y, z);
                if (lightLevel > 0)
                {
                    int temp = prevLightLevel - lightDamp;
                    //如果前一个物块比当前物块的太阳光亮,那么减弱当前物块的亮度
                    if (temp > lightLevel)
                    {
                        int nextLightLevel = curLightLevel - lightDamp - 1;
                        if (nextLightLevel < 0)
                        {
                            nextLightLevel = 0;
                        }
                        //如果最终结果没有发生改变,那么不收缩
                        if (nextLightLevel == lightLevel)
                        {
                            return;
                        }
                        chunk.SetSunLight(x, y, z, nextLightLevel, true);
                        if (!_changedList.Contains(chunk))
                        {
                            _changedList.Add(chunk);
                        }
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        _lightBfsQueue.Enqueue(NodeCache.Instance.GetShrinkNode(nextIndex, lightLevel, nextLightLevel, chunk));
                    }
                    //如果前一个物块比当前物块的太阳光暗,那么增强前一个物块的亮度
                    else if (temp < lightLevel)
                    {
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk));
                    }
                }
            }
        }
예제 #8
0
 private static BlockAttributeCalculator[] GetInitArr()
 {
     BlockAttributeCalculator[] arrMap = new BlockAttributeCalculator[256];
     foreach (var item in Enum.GetValues(typeof(BlockType)))
     {
         string className = "MTB.BAC_" + ((BlockType)item).ToString();
         Type   t         = Type.GetType(className);
         arrMap[(byte)item] = Activator.CreateInstance(t) as BlockAttributeCalculator;
     }
     return(arrMap);
 }
예제 #9
0
        private void SpreadInPosDown(int x, int y, int z, Chunk chunk, int prevLightLevel, int curLightLevel)
        {
            if (curLightLevel >= WorldConfig.Instance.maxLightLevel)
            {
                return;
            }
            //当前高度大于光照高度,往下收缩,不管亮度是否大于自己
            if (y >= chunk.GetHeight(x, z, true))
            {
                return;
            }
            Block b = chunk.GetBlock(x, y, z, true);
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int lightDamp = calculator.LightDamp(b.ExtendId);

            if (lightDamp < WorldConfig.Instance.maxLightLevel)
            {
                int lightLevel = chunk.GetSunLight(x, y, z);
                if (lightLevel > 0)
                {
                    int temp = prevLightLevel - lightDamp;
                    //向下收缩,考虑到都为15的情况,相等的情况下也收缩掉
                    if (temp > lightLevel || (temp <= WorldConfig.Instance.maxLightLevel && lightLevel == WorldConfig.Instance.maxLightLevel))
                    {
                        int nextLightLevel = curLightLevel - lightDamp - 1;
                        if (nextLightLevel < 0)
                        {
                            nextLightLevel = 0;
                        }
                        if (nextLightLevel == lightLevel)
                        {
                            return;
                        }
                        chunk.SetSunLight(x, y, z, nextLightLevel, true);
                        if (!_changedList.Contains(chunk))
                        {
                            _changedList.Add(chunk);
                        }
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        if (temp <= WorldConfig.Instance.maxLightLevel && lightLevel == WorldConfig.Instance.maxLightLevel)
                        {
                            lightLevel = nextLightLevel;
                        }
                        _lightBfsQueue.Enqueue(NodeCache.Instance.GetShrinkNode(nextIndex, lightLevel, nextLightLevel, chunk));
                    }
                    //如果前一个物块比当前物块的太阳光暗,那么增强前一个物块的亮度
                    else if (temp < lightLevel)
                    {
                        int nextIndex = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                        _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, lightLevel, chunk));
                    }
                }
            }
        }
예제 #10
0
        protected void AddUV(FilterMeshData filterMeshData, BlockType type, byte extendId, Direction direction)
        {
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(type);
            Rect  uvRect = calculator.GetUVRect(extendId, direction);
            float scale  = uvRect.width * 0.03f;

            filterMeshData.uv.Add(new Vector2(uvRect.x + uvRect.width - scale, uvRect.y + uvRect.height - scale));
            filterMeshData.uv.Add(new Vector2(uvRect.x + scale, uvRect.y + uvRect.height - scale));
            filterMeshData.uv.Add(new Vector2(uvRect.x + scale, uvRect.y + scale));
            filterMeshData.uv.Add(new Vector2(uvRect.x + uvRect.width - scale, uvRect.y + scale));
        }
예제 #11
0
        private void UpdateSunLightHeight(int x, int y, int z, Block block)
        {
            int height = GetHeight(x, z);

            height = y <= height ? height : y + 1;
            bool isLight       = true;
            int  sunLightLevel = WorldConfig.Instance.maxLightLevel;
            int  ty;

            for (ty = height - 1; ty >= 0; ty--)
            {
                Block b = GetBlock(x, ty, z, true);
                BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
                int lightDamp = calculator.LightDamp(b.ExtendId);

                if (lightDamp != 0 && isLight)
                {
                    SetHeight(x, z, ty + 1);
                    isLight = false;
                }

                sunLightLevel -= lightDamp;
                if (sunLightLevel < 0)
                {
                    sunLightLevel = 0;
                }
                SetSunLight(x, ty, z, sunLightLevel);
                if (sunLightLevel == 0)
                {
                    break;
                }
            }
            height = ty - 1;
            for (ty = height; ty >= 0; ty--)
            {
                if (GetSunLight(x, ty, z) > 0)
                {
                    SetSunLight(x, ty, z, 0);
                }
                else
                {
                    break;
                }
            }
        }
예제 #12
0
        private void CreateExplodeParticle(WorldPos pos, Block block, Vector3 normal)
        {
            ParticleSystem explode = particleQueue.Dequeue();

            Renderer  render = explode.GetComponent <Renderer>();
            Direction dir    = Direction.left;
            //更新光照
            int      direction = CheckNormal(normal);
            WorldPos lightPos  = pos;

            if (direction != 0)
            {
                dir      = (Direction)direction;
                lightPos = new WorldPos(pos.x + Mathf.RoundToInt(normal.x), pos.y + Mathf.RoundToInt(normal.y),
                                        pos.z + Mathf.RoundToInt(normal.z));
            }

            int   sunLightLevel   = World.world.GetSunLight(lightPos.x, lightPos.y, lightPos.z);
            int   blockLightLevel = World.world.GetBlockLight(lightPos.x, lightPos.y, lightPos.z);
            float lightIntensity  = MTBSkyBox.Instance.GetLightIntensity(sunLightLevel, blockLightLevel);

            render.material.SetFloat("_lightIntensity", lightIntensity);
            //更新贴图
            ResetExplode(explode);
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(block.BlockType);
            byte             resExtendId        = calculator.GetResourceExtendId(block.ExtendId);
            WorldTextureType type = WorldTextureProvider.Instance.GetTextureType(block.BlockType, resExtendId);

            render.material.mainTexture = WorldTextureProvider.Instance.GetAtlasTexture(type);
            Rect rect = WorldTextureProvider.Instance.GetBlockTextureRect(block.BlockType, resExtendId, dir);

            if (rect != null)
            {
                render.material.SetFloat("_OffsetX", rect.x);
                render.material.SetFloat("_OffsetY", rect.y);
                render.material.SetFloat("_Width", rect.width);
                render.material.SetFloat("_Random", UnityEngine.Random.Range(0, 1f));
                explode.transform.position = new Vector3(pos.x + 0.5f, pos.y + 0.1f, pos.z + 0.5f);
            }
            explode.Play();
            particleQueue.Enqueue(explode);
        }
예제 #13
0
 void Update()
 {
     if (!_isFly)
     {
         _curTime += Time.deltaTime;
         if (_curTime > disappearTime)
         {
             On_SelfDisappear(this);
         }
         WorldPos pos   = Terrain.GetWorldPos(this.transform.position);
         Block    block = World.world.GetBlock(pos.x, pos.y, pos.z);
         BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(block.BlockType);
         int   sunLight       = World.world.GetSunLight(pos.x, pos.y, pos.z);
         int   blockLight     = World.world.GetBlockLight(pos.x, pos.y, pos.z);
         float lightIntensity = MTBSkyBox.Instance.GetLightIntensity(sunLight, blockLight);
         render.material.SetFloat("_lightIntensity", lightIntensity);
         if (calculator.GetMeshColliderType(block.ExtendId) == MeshColliderType.terrainCollider)
         {
             On_SelfDisappear(this);
         }
     }
     else
     {
         if (_player != null)
         {
             Vector3 dis = _player.transform.position + new Vector3(0, 1.5f, 0) - this.transform.position;
             if (dis.magnitude < 0.3f)
             {
                 On_SelfDisappear(this);
                 return;
             }
             Vector3 v = dis.normalized * flySpeed;
             this.transform.position += v * Time.deltaTime;
         }
         else
         {
             On_SelfDisappear(this);
         }
     }
 }
예제 #14
0
        private List <Chunk> GetBlockLightChangeChunks(Chunk chunk, int x, int y, int z, Block b, List <Chunk> list)
        {
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int curBlockLightLevel = calculator.LightLevel(b.ExtendId);
            int blockLightLevel    = chunk.GetBlockLight(x, y, z, true);

            if (curBlockLightLevel > blockLightLevel)
            {
                int             index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                LightSpreadNode node  = NodeCache.Instance.GetSpreadNode(index, curBlockLightLevel, chunk);
                _blockLightSpread.AddSpreadNode(node);
                chunk.SetBlockLight(x, y, z, curBlockLightLevel, true);
            }
            else if (curBlockLightLevel < blockLightLevel)
            {
                int             index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                LightShrinkNode node  = NodeCache.Instance.GetShrinkNode(index, blockLightLevel, curBlockLightLevel, chunk);
                _blockLightShrink.AddShrinkNode(node);
                chunk.SetBlockLight(x, y, z, curBlockLightLevel, true);
            }
            List <Chunk> spreadList = _blockLightSpread.SpreadInChunk(chunk);
            List <Chunk> shrinkList = _blockLightShrink.ShrinkInChunk(chunk);

            for (int i = 0; i < spreadList.Count; i++)
            {
                if (!list.Contains(spreadList[i]))
                {
                    list.Add(spreadList[i]);
                }
            }
            for (int i = 0; i < shrinkList.Count; i++)
            {
                if (!list.Contains(shrinkList[i]))
                {
                    list.Add(shrinkList[i]);
                }
            }
            return(list);
        }
예제 #15
0
        public override void SetBlock(World world, int x, int y, int z, Block block, bool notify = true)
        {
            if (!IsHeightLimit(y))
            {
                return;
            }
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(block.BlockType);
            Direction direction = calculator.GetFaceDirection(block.ExtendId);
            WorldPos  offset    = new WorldPos();

            if (direction == Direction.front)
            {
                offset = new WorldPos(x - 1, y, z);
            }
            if (direction == Direction.back)
            {
                offset = new WorldPos(x + 1, y, z);
            }
            if (direction == Direction.left)
            {
                offset = new WorldPos(x, y, z - 1);
            }
            if (direction == Direction.right)
            {
                offset = new WorldPos(x, y, z + 1);
            }
            byte extendId = (byte)(block.ExtendId & 7);

            if (world.GetBlock(offset.x, offset.y, offset.z).BlockType != BlockType.Air)
            {
                return;
            }
            Block tempBlock = new Block(block.BlockType, extendId);

            SetBlockAndNotify(world, offset.x, offset.y, offset.z, tempBlock);
            SetBlockAndNotify(world, x, y, z, block);
            world.CheckAndRecalculateMesh(offset.x, offset.y, offset.z, tempBlock);
            world.CheckAndRecalculateMesh(x, y, z, block);
        }
        private void NormalSunLightFill(Chunk chunk)
        {
            int  sunLightLevel;
            bool isLight;

            for (int x = 0; x < Chunk.chunkWidth; x++)
            {
                for (int z = 0; z < Chunk.chunkDepth; z++)
                {
                    sunLightLevel = WorldConfig.Instance.maxLightLevel;
                    isLight       = true;
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block b = chunk.GetBlock(x, y, z, true);

                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
                        int lightDamp = calculator.LightDamp(b.ExtendId);

                        if (lightDamp != 0 && isLight)
                        {
                            chunk.SetHeight(x, z, y + 1);
                            isLight = false;
                        }

                        sunLightLevel -= lightDamp;
                        if (sunLightLevel > 0)
                        {
                            chunk.SetSunLight(x, y, z, sunLightLevel);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
예제 #17
0
 //特殊网格计算(不能确定当前坐标会在chunk中)
 public virtual void CalculateSpecialMesh(Chunk chunk, int x, int y, int z, MeshData meshData, Block self
                                          , Block other, BlockAttributeCalculator otherCalculator, Direction direction)
 {
 }
        private void SpreadFromOtherChunk(Chunk chunk)
        {
            Chunk otherChunk;

            //curChunk_X - 1
            otherChunk = _world.GetChunk(chunk.worldPos.x - Chunk.chunkWidth, 0, chunk.worldPos.z);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int z = 0; z < Chunk.chunkDepth; z++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(0, y, z, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(0, y, z, true);
                            int otherLightLevel = otherChunk.GetSunLight(Chunk.chunkWidth - 1, y, z, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(0, y, z, nextLightLevel, true);
                                int nextIndex = (0 * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
            //curChunk_x + Chunk.chunkWidth
            otherChunk = _world.GetChunk(chunk.worldPos.x + Chunk.chunkWidth, 0, chunk.worldPos.z);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int z = 0; z < Chunk.chunkDepth; z++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(Chunk.chunkWidth - 1, y, z, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(Chunk.chunkWidth - 1, y, z, true);
                            int otherLightLevel = otherChunk.GetSunLight(0, y, z, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(Chunk.chunkWidth - 1, y, z, nextLightLevel, true);
                                int nextIndex = ((Chunk.chunkWidth - 1) * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
            //curChunk_z - Chunk.chunkDepth
            otherChunk = _world.GetChunk(chunk.worldPos.x, 0, chunk.worldPos.z - Chunk.chunkDepth);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int x = 0; x < Chunk.chunkDepth; x++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(x, y, 0, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(x, y, 0, true);
                            int otherLightLevel = otherChunk.GetSunLight(x, y, Chunk.chunkDepth - 1, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(x, y, 0, nextLightLevel, true);
                                int nextIndex = (x * Chunk.chunkDepth + 0) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
            //curChunk_z + Chunk.chunkDepth
            otherChunk = _world.GetChunk(chunk.worldPos.x, 0, chunk.worldPos.z + Chunk.chunkDepth);
            if (otherChunk != null && otherChunk.isLightDataPrepared)
            {
                for (int x = 0; x < Chunk.chunkDepth; x++)
                {
                    for (int y = Chunk.chunkHeight - 1; y >= 0; y--)
                    {
                        Block curBlock = chunk.GetBlock(x, y, Chunk.chunkDepth - 1, true);
                        BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                        int lightDamp = calculator.LightDamp(curBlock.ExtendId);
                        if (lightDamp < 15)
                        {
                            int curLightLevel   = chunk.GetSunLight(x, y, Chunk.chunkDepth - 1, true);
                            int otherLightLevel = otherChunk.GetSunLight(x, y, 0, true);
                            int nextLightLevel  = otherLightLevel - lightDamp - 1;
                            if (nextLightLevel > curLightLevel)
                            {
                                chunk.SetSunLight(x, y, Chunk.chunkDepth - 1, nextLightLevel, true);
                                int nextIndex = (x * Chunk.chunkDepth + Chunk.chunkDepth - 1) * Chunk.chunkHeight + y;
                                _lightSpread.AddSpreadNode(NodeCache.Instance.GetSpreadNode(nextIndex, nextLightLevel, chunk));
                            }
                        }
                    }
                }
            }
        }
예제 #19
0
        private void RefreshColliderMask(bool[] faceMask, MeshColliderType[] colliderMask, int maskIndex, Block bA, Block bB, BlockAttributeCalculator aBAC, BlockAttributeCalculator bBAC, int direction)
        {
            MeshColliderType a = aBAC.GetMeshColliderType(bA.ExtendId);
            MeshColliderType b = bBAC.GetMeshColliderType(bB.ExtendId);

            if (a == b)
            {
                faceMask[maskIndex]     = true;
                colliderMask[maskIndex] = MeshColliderType.none;
            }
            else if (b == MeshColliderType.none)
            {
                faceMask[maskIndex]     = true;
                colliderMask[maskIndex] = aBAC.GetMeshColliderType(bA.ExtendId);
            }
            else if (a == MeshColliderType.none)
            {
                faceMask[maskIndex]     = false;
                colliderMask[maskIndex] = bBAC.GetMeshColliderType(bB.ExtendId);
            }
            else
            {
                if (a == MeshColliderType.terrainCollider)
                {
                    faceMask[maskIndex]     = true;
                    colliderMask[maskIndex] = aBAC.GetMeshColliderType(bA.ExtendId);
                }
                else
                {
                    faceMask[maskIndex]     = false;
                    colliderMask[maskIndex] = bBAC.GetMeshColliderType(bB.ExtendId);
                }
            }
        }
예제 #20
0
 public override void CalculateSpecialMesh(Chunk chunk, int x, int y, int z, MeshData meshData, Block self, Block other, BlockAttributeCalculator otherCalculator, Direction direction)
 {
     //因为会渲染六次(六个正方向)
     if (direction == Direction.right)
     {
         meshData.useDoubleFace = true;
         FaceDataOne(chunk, x, y, z, meshData, self.ExtendId);
         meshData.useDoubleFace = MeshData.DefaultUseDoubleFace;
     }
 }
예제 #21
0
        public void CalculateSectionMesh(Section section, MeshData meshData)
        {
            MeshCalculateWay way = GetCalculateWay(section);

            if (way == MeshCalculateWay.None)
            {
                return;
            }
            for (int d = 0; d < 3; d++)
            {
                int i, j, k, l, w, h,
                    u = (d + 1) % 3,
                    v = (d + 2) % 3;
                ClearIntArr(x);
                ClearIntArr(q);
//				int[] x = new int[]{0,0,0};
//				int[] q = new int[]{0,0,0};

                int direction = d + 1;

                q[d] = 1;
                if (way == MeshCalculateWay.Side)
                {
                    x[d] = dims[d] - 1;
                }
                else
                {
                    x[d] = 0;
                }
                for (; x[d] < dims[d];)
                {
                    int  n         = 0;
                    bool bBInRange = x[d] < dims[d] - 1;
                    for (x[v] = 0; x[v] < dims[v]; x[v]++)
                    {
                        for (x[u] = 0; x[u] < dims[u]; x[u]++)
                        {
                            int x1 = x[0], y1 = x[1], z1 = x[2], x2 = x1 + q[0], y2 = y1 + q[1], z2 = z1 + q[2];

                            Block bA = (x[d] < 1 || way == MeshCalculateWay.Side) ? section.GetBlock(x1, y1, z1, true) : _prevBlocks[n];
                            BlockAttributeCalculator aBAC = BlockAttributeCalculatorFactory.GetCalculator(bA.BlockType);

                            Block bB = section.GetBlock(x2, y2, z2, bBInRange);
                            BlockAttributeCalculator bBAC = BlockAttributeCalculatorFactory.GetCalculator(bB.BlockType);

                            CalculateRenderMesh(section.chunk, meshData, x1, y1 + section.chunkOffsetY, z1, x2, y2 + section.chunkOffsetY, z2, bA, bB, aBAC, bBAC, direction, bBInRange);
                            RefreshRenderMask(_renderMask, _renderDirectionMask, _curRenderBlocks, _sunLightsMask, _blockLightsMask, n, section, x1, y1, z1, x2, y2, z2, bA, bB, aBAC, bBAC, bBInRange, direction);
                            RefreshColliderMask(_faceMask, _colliderMask, n, bA, bB, aBAC, bBAC, direction);

                            _prevBlocks[n] = bB;
                            n++;
                        }
                    }
                    x[d]++;

//					//贪心简化碰撞网格
//					n = 0;
//					for (j = 0; j < dims[v]; j++) {
//						for (i = 0; i < dims[u];) {
//							bool c = _faceMask[n];
//							MeshColliderType c1 = _colliderMask[n];
//							if(c1 != MeshColliderType.none)
//							{
//								for (w = 1;i + w < dims[u] && c1 == _colliderMask[n + w] && c == _faceMask[n + w] ; w++);
//								bool done = false;
//								for (h = 1; j + h < dims[v]; h++) {
//									for (k = 0; k < w; k++) {
//										int doneIndex = n + k + h * dims[u];
//										if(c1 != _colliderMask[doneIndex] || c != _faceMask[doneIndex])
//										{
//											done = true;
//											break;
//										}
//									}
//									if(done)break;
//								}
//
//								x[u] = i; x[v] = j;
//								ClearIntArr(du);
//								ClearIntArr(dv);
////								int[] du = new int[]{0,0,0};
////								int[] dv = new int[]{0,0,0};
//								du[u] = w;
//								dv[v] = h;
//								//因为shader的需求,这边不能-0.5
//								AddFace(c,c1,meshData,MeshBaseDataCache.Instance.GetVector3(x[0],x[1] + section.chunkOffsetY,x[2]),
//								        MeshBaseDataCache.Instance.GetVector3(x[0] + du[0],x[1] + du[1] + section.chunkOffsetY,x[2] + du[2]),
//								        MeshBaseDataCache.Instance.GetVector3(x[0] + du[0] + dv[0],x[1] + du[1] + dv[1] + section.chunkOffsetY,x[2] + du[2] + dv[2]),
//								        MeshBaseDataCache.Instance.GetVector3(x[0] + dv[0],x[1] + dv[1] + section.chunkOffsetY,x[2] + dv[2]));
//								for (l = 0; l < h; l++) {
//									for (k = 0; k < w; k++) {
//										int maskIndex = n + k + l * dims[u];
//										_faceMask[maskIndex] = true;
//										_colliderMask[maskIndex] = MeshColliderType.none;
//									}
//								}
//								i+=w;
//								n+=w;
//							}
//							else
//							{
//								i++;n++;
//							}
//						}
//					}

                    //贪心简化渲染网格

                    n = 0;
                    for (j = 0; j < dims[v]; j++)
                    {
                        for (i = 0; i < dims[u];)
                        {
                            bool      canRender       = _renderMask[n];
                            Direction renderDirection = _renderDirectionMask[n];
                            Block     curBlock        = _curRenderBlocks[n];
                            BlockAttributeCalculator curCalculator = BlockAttributeCalculatorFactory.GetCalculator(curBlock.BlockType);
                            LightVertice             sunLight      = _sunLightsMask[n];
                            LightVertice             blockLight    = _blockLightsMask[n];
                            if (canRender)
                            {
                                for (w = 1; i + w < dims[u] && _renderMask[n + w] && renderDirection == _renderDirectionMask[n + w] &&
                                     curCalculator.CanCombineWithBlock(curBlock.ExtendId, _curRenderBlocks[n + w]) &&
                                     sunLight.EqualOther(_sunLightsMask[n + w]) && blockLight.EqualOther(_blockLightsMask[n + w]); w++)
                                {
                                    ;
                                }
                                bool done = false;
                                for (h = 1; j + h < dims[v]; h++)
                                {
                                    for (k = 0; k < w; k++)
                                    {
                                        int doneIndex = n + k + h * dims[u];
                                        if (!_renderMask[doneIndex] || renderDirection != _renderDirectionMask[doneIndex] ||
                                            !curCalculator.CanCombineWithBlock(curBlock.ExtendId, _curRenderBlocks[doneIndex]) ||
                                            !sunLight.EqualOther(_sunLightsMask[doneIndex]) || !blockLight.EqualOther(_blockLightsMask[doneIndex]))
                                        {
                                            done = true;
                                            break;
                                        }
                                    }
                                    if (done)
                                    {
                                        break;
                                    }
                                }

                                x[u] = i; x[v] = j;
                                ClearIntArr(du);
                                ClearIntArr(dv);
//								int[] du = new int[]{0,0,0};
//								int[] dv = new int[]{0,0,0};
                                du[u] = w;
                                dv[v] = h;
                                curCalculator.CalculateMesh(section.chunk, meshData, curBlock, renderDirection,
                                                            MeshBaseDataCache.Instance.GetVector3(x[0], x[1] + section.chunkOffsetY, x[2]),
                                                            MeshBaseDataCache.Instance.GetVector3(x[0] + du[0], x[1] + du[1] + section.chunkOffsetY, x[2] + du[2]),
                                                            MeshBaseDataCache.Instance.GetVector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1] + section.chunkOffsetY, x[2] + du[2] + dv[2]),
                                                            MeshBaseDataCache.Instance.GetVector3(x[0] + dv[0], x[1] + dv[1] + section.chunkOffsetY, x[2] + dv[2]), sunLight, blockLight);
                                for (l = 0; l < h; l++)
                                {
                                    for (k = 0; k < w; k++)
                                    {
                                        int maskIndex = n + k + l * dims[u];
                                        _renderMask[maskIndex] = false;
                                    }
                                }
                                i += w;
                                n += w;
                            }
                            else
                            {
                                i++; n++;
                            }
                        }
                    }
                }
            }
            //计算boxcollider
            int nn = 0;

            for (int y = 0; y < dims[1]; y++)
            {
                for (int x = 0; x < dims[0]; x++)
                {
                    for (int z = 0; z < dims[2]; z++)
                    {
                        Block block = section.GetBlock(x, y, z, true);
                        BlockAttributeCalculator calculator   = BlockAttributeCalculatorFactory.GetCalculator(block.BlockType);
                        MeshColliderType         colliderType = calculator.GetMeshColliderType(block.ExtendId);
                        _terrainColliderMask[nn] = colliderType;
                        nn++;
                    }
                }
            }
            nn = 0;
            int dd;
            int ww;
            int hh;
            int kk;
            int ll;
            int mm;

            for (int y = 0; y < dims[1]; y++)
            {
                for (int x = 0; x < dims[0]; x++)
                {
                    for (int z = 0; z < dims[2];)
                    {
                        MeshColliderType flag = _terrainColliderMask[nn];
                        if (flag != MeshColliderType.none)
                        {
                            for (dd = 1; z + dd < dims[2] && flag == _terrainColliderMask[nn + dd]; dd++)
                            {
                                ;
                            }
                            bool done = false;
                            for (ww = 1; x + ww < dims[0]; ww++)
                            {
                                for (kk = 0; kk < dd; kk++)
                                {
                                    int doneIndex = nn + kk + ww * dims[2];
                                    if (flag != _terrainColliderMask[doneIndex])
                                    {
                                        done = true;
                                        break;
                                    }
                                }
                                if (done)
                                {
                                    break;
                                }
                            }
                            done = false;
                            for (hh = 1; y + hh < dims[1]; hh++)
                            {
                                for (ll = 0; ll < ww; ll++)
                                {
                                    for (kk = 0; kk < dd; kk++)
                                    {
                                        int doneIndex = nn + kk + ll * dims[2] + hh * dims[0] * dims[2];
                                        if (flag != _terrainColliderMask[doneIndex])
                                        {
                                            done = true;
                                            break;
                                        }
                                    }
                                    if (done)
                                    {
                                        break;
                                    }
                                }
                                if (done)
                                {
                                    break;
                                }
                            }

                            Vector3 min    = new Vector3(x, y, z);
                            Vector3 max    = new Vector3(x + ww, y + hh, z + dd);
                            Vector3 center = (min + max) / 2;
                            center.y += section.chunkOffsetY;
                            Vector3 size = max - min;
                            if (flag == MeshColliderType.terrainCollider)
                            {
                                meshData.terrainCollider.AddBox(center, size);
                            }
                            else
                            {
                                meshData.supportCollider.AddBox(center, size);
                            }

                            for (mm = 0; mm < hh; mm++)
                            {
                                for (ll = 0; ll < ww; ll++)
                                {
                                    for (kk = 0; kk < dd; kk++)
                                    {
                                        int maskIndex = nn + kk + ll * dims[2] + mm * dims[0] * dims[2];
                                        _terrainColliderMask[maskIndex] = MeshColliderType.none;
                                    }
                                }
                            }
                            nn += dd;
                            z  += dd;
                        }
                        else
                        {
                            nn++;
                            z++;
                        }
                    }
                }
            }
        }
예제 #22
0
        public override void CalculateSpecialMesh(Chunk chunk, int x, int y, int z, MeshData meshData, Block self, Block other, BlockAttributeCalculator otherCalculator, Direction direction)
        {
            //因为会计算六次
            if (direction != Direction.right)
            {
                return;
            }
            if (!IsModelCenter(self.ExtendId))
            {
                return;
            }
            ModelData modelData  = ModelDataManager.Instance.GetModelData((int)self.BlockType);
            Direction face       = GetFaceDirection(self.ExtendId);
            Vector2   rotate     = GetRotateSinAndCos(face);
            int       sunLight   = chunk.GetSunLight(x, y, z, true);
            int       blockLight = chunk.GetBlockLight(x, y, z, true);
            Rect      rect       = GetUVRect(self.ExtendId, direction);

            meshData.useRenderDataForCol = true;
            int verticesIndex    = meshData.GetCurVerticesIndex();
            int colVerticesIndex = meshData.GetCurColVerticesIndex();

            for (int i = 0; i < modelData.vertices.Length; i++)
            {
                Vector3[] vertices = modelData.vertices;
                Vector2[] uvs      = modelData.uvs;

                float verX  = vertices[i].x * rotate.y + vertices[i].z * rotate.x;
                float verZ  = -vertices[i].x * rotate.x + vertices[i].z * rotate.y;
                float realX = x + 0.5f + verX;
                float realY = y + vertices[i].y;
                float realZ = z + 0.5f + verZ;
                //添加渲染网格
                meshData.AddVertice(MeshBaseDataCache.Instance.GetVector3(realX, realY, realZ));
                meshData.AddColor(MeshBaseDataCache.Instance.GetColor(LightConst.lightColor[sunLight], LightConst.lightColor[blockLight], 0, 2));
                //这里要转换uv坐标
                meshData.AddUV(MeshBaseDataCache.Instance.GetVector2(rect.x + uvs[i].x * rect.width, rect.y + uvs[i].y * rect.height));

                //添加碰撞网格
                meshData.AddColVertice(MeshBaseDataCache.Instance.GetVector3(realX, realY, realZ));
            }
            for (int i = 0; i < modelData.triangles.Length; i++)
            {
                meshData.AddTriangle(verticesIndex + modelData.triangles[i]);

                meshData.AddColTriangle(colVerticesIndex + modelData.triangles[i]);
            }
            meshData.useRenderDataForCol = MeshData.DefaultUseRenderDataForCol;
        }
        public override void ActionIn()
        {
            float screenX = _playerController.playerInputState.X;
            float screenY = _playerController.playerInputState.Y;

            BlockMaskController.Instance.Do(screenX, screenY, _playerController.transform.position, distance);
            RaycastHit hit;
            int        handMaterialId = _playerController.playerAttribute.handMaterialId;

            if (handMaterialId <= 0)
            {
                return;
            }
            Item item = ItemManager.Instance.GetItem(handMaterialId);

            if (item.itemType != (int)ItemType.Block)
            {
                return;
            }
            if (Terrain.RayToWorld(screenX, screenY, _playerController.transform.position,
                                   distance, out hit, oppoMaskLayer))
            {
                WorldPos pos = Terrain.GetWorldPos(hit, true);
                if (hit.collider.GetComponentInParent <ChunkObj>() == null)
                {
                    return;
                }
                if (!Terrain.CheckPosCanPlaced(_playerController.transform, pos))
                {
                    return;
                }
                Block handBlock = new Block((BlockType)item.sceneBlockType, item.sceneBlockExtendId);

                BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(handBlock.BlockType);
                if (calculator is BAC_ModelBlock)
                {
                    Vector3 forward  = _gameObjectController.transform.forward;
                    float   degree   = Vector2.Angle(Vector2.right, new Vector2(forward.x, forward.z));
                    byte    extendId = 8;
                    if (degree < 45)
                    {
                        extendId |= 3;
                    }
                    else if (degree > 135)
                    {
                        extendId |= 1;
                    }
                    else if (forward.z > 0)
                    {
                        extendId |= 2;
                    }
                    handBlock = new Block(BlockType.Block_100, extendId);
                }

                int decType = HasActionObjectManager.Instance.plantManager.checkIsPlantSeedling(handMaterialId);
                if (decType != -1)
                {
                    HasActionObjectManager.Instance.plantManager.buildPlant(new Vector3(pos.x, pos.y, pos.z), (DecorationType)decType);
                    return;
                }

                Terrain.SetBlock(pos, handBlock);
            }
        }
예제 #24
0
 public override void CalculateSpecialMesh(Chunk chunk, int x, int y, int z, MeshData meshData, Block self, Block other, BlockAttributeCalculator otherCalculator, Direction direction)
 {
     if (other.BlockType == BlockType.Air || (direction == Direction.up && other.BlockType != BlockType.FlowingWater && other.BlockType != BlockType.StillWater) ||
         otherCalculator.GetBlockRenderType(other.ExtendId) == MTB.BlockRenderType.Part && other.BlockType != BlockType.FlowingWater && other.BlockType != BlockType.StillWater)
     {
         meshData.useTransparentTexture = true;
         meshData.useDoubleFace         = true;
         CalculatorDirection(chunk, x, y, z, meshData, self.ExtendId, direction);
         meshData.useTransparentTexture = MeshData.DefaultUseTransparentTexture;
         meshData.useDoubleFace         = MeshData.DefaultUseDoubleFace;
     }
 }
예제 #25
0
        private List <Chunk> GetSunLightChangeChunks(Chunk chunk, int x, int y, int z, Block b, List <Chunk> list)
        {
            List <Chunk>             spreadList = null;
            List <Chunk>             shrinkList = null;
            BlockAttributeCalculator calculator = BlockAttributeCalculatorFactory.GetCalculator(b.BlockType);
            int lightDamp  = calculator.LightDamp(b.ExtendId);
            int height     = chunk.GetHeight(x, z);
            int lightLevel = chunk.GetSunLight(x, y, z, true);
            int curLightLevel;

            if (y >= height - 1)
            {
                for (int ty = y; ty >= height; ty--)
                {
                    Block nextBlock = chunk.GetBlock(x, ty, z);
                    BlockAttributeCalculator nextCalculator = BlockAttributeCalculatorFactory.GetCalculator(nextBlock.BlockType);
                    int nextLightDamp = nextCalculator.LightDamp(nextBlock.ExtendId);
                    if (nextLightDamp > 0)
                    {
                        height = ty + 1;
                        //更新高度
                        chunk.SetHeight(x, z, height, true);
                        break;
                    }
                }
                curLightLevel = WorldConfig.Instance.maxLightLevel - lightDamp;
                if (curLightLevel < 0)
                {
                    curLightLevel = 0;
                }
            }
            else
            {
                int leftSunLight   = chunk.GetSunLight(x - 1, y, z);
                int rightSunLight  = chunk.GetSunLight(x + 1, y, z);
                int topSunLight    = chunk.GetSunLight(x, y + 1, z);
                int bottomSunLight = chunk.GetSunLight(x, y - 1, z);
                int frontSunLight  = chunk.GetSunLight(x, y, z + 1);
                int backSunLight   = chunk.GetSunLight(x, y, z - 1);

                int maxSunLight = GetMax(leftSunLight, rightSunLight, topSunLight, bottomSunLight,
                                         frontSunLight, backSunLight);
                curLightLevel = maxSunLight - lightDamp - 1;
                if (curLightLevel < 0)
                {
                    curLightLevel = 0;
                }
            }

            if (curLightLevel < lightLevel)
            {
                chunk.SetSunLight(x, y, z, curLightLevel, true);
                int             index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                LightShrinkNode node  = NodeCache.Instance.GetShrinkNode(index, lightLevel, curLightLevel, chunk);
                _sunLightShrink.AddShrinkNode(node);
                shrinkList = _sunLightShrink.ShrinkInChunk(chunk);
            }
            else if (curLightLevel > lightLevel)
            {
                chunk.SetSunLight(x, y, z, curLightLevel, true);
                int             index = (x * Chunk.chunkDepth + z) * Chunk.chunkHeight + y;
                LightSpreadNode node  = NodeCache.Instance.GetSpreadNode(index, curLightLevel, chunk);
                _sunLightSpread.AddSpreadNode(node);
                spreadList = _sunLightSpread.SpreadInChunk(chunk);
            }

            if (spreadList != null)
            {
                for (int i = 0; i < spreadList.Count; i++)
                {
                    if (!list.Contains(spreadList[i]))
                    {
                        list.Add(spreadList[i]);
                    }
                }
            }
            if (shrinkList != null)
            {
                for (int i = 0; i < shrinkList.Count; i++)
                {
                    if (!list.Contains(shrinkList[i]))
                    {
                        list.Add(shrinkList[i]);
                    }
                }
            }
            return(list);
        }