public static float[] CreateCubeNormals()
        {
            List <float> normals = new List <float>();

            void AppendVertexes(TextureType side)
            {
                var normal = FaceSides.Parse(side);

                for (int i = 0; i < 4; i++)
                {
                    normals.Add(normal.x);
                    normals.Add(normal.y);
                    normals.Add(normal.z);
                }
            }

            AppendVertexes(TextureType.up);
            AppendVertexes(TextureType.down);
            AppendVertexes(TextureType.north);
            AppendVertexes(TextureType.south);
            AppendVertexes(TextureType.east);
            AppendVertexes(TextureType.west);

            return(normals.ToArray());
        }
        public static void AppendFace(TextureType side, float[] from, float[] to, Vector3 rotation, Vector3 rotationOrigin,
                                      ref float[] vertexes, ref float[] normals, int startIndex)
        {
            FaceSides faceSide = FaceSides.Parse(side); //TextureType parsed to FaceSides, also a normal of this face
            Vector3   normal   = faceSide.ToVec();

            float[] unitFace = _cube[faceSide]; //one side of the cube in unit size

            float x = from[0] / 16f;
            float y = from[1] / 16f;
            float z = from[2] / 16f;

            float sx = to[0] / 16f - x; //the size of the cube part
            float sy = to[1] / 16f - y;
            float sz = to[2] / 16f - z;

            for (var i = 0; i < unitFace.Length; i += 3)
            {
                var vertex = RotateVertex(new Vector3(
                                              x + unitFace[i] * sx,
                                              y + unitFace[i + 1] * sy,
                                              z + unitFace[i + 2] * sz), rotation, rotationOrigin);

                vertexes[startIndex + i]     = vertex.X;
                vertexes[startIndex + i + 1] = vertex.Y;
                vertexes[startIndex + i + 2] = vertex.Z;

                var nrm = RotateVertex(normal, rotation, rotationOrigin);

                normals[startIndex + i]     = nrm.X;
                normals[startIndex + i + 1] = nrm.Y;
                normals[startIndex + i + 2] = nrm.Z;
            }
        }
        //unused for now
        public void AppendVertexesForSide(FaceSides side, List <float> vertexes, BlockPos offset)
        {
            /*
             * top = 0
             * bottom = 1
             * north = 2
             * south = 3
             * west = 4
             * east = 5
             * --> these are used as indexes of the faces, since the model vertex data is added in the same exact order of the TextureType enum values
             */
            if (!FaceSides.Parse(side, out var parsed)) //FaceSides is a struct containing Vector2 values (normals)
            {
                return;
            }

            int faceIndex = (int)parsed * 12;

            for (int i = 0; i < 12; i += 3)
            {
                vertexes.Add(_vertexes[faceIndex + i] + offset.X);
                vertexes.Add(_vertexes[faceIndex + i + 1] + offset.Y);
                vertexes.Add(_vertexes[faceIndex + i + 2] + offset.Z);
            }
        }
        //TODO - only use these when the block model is one 1x1x1 big cube
        public void AppendVertexDataForSide(FaceSides side, List <float> vertexes, List <float> normals, List <float> uvs, BlockPos offset)
        {
            if (!FaceSides.Parse(side, out var parsed)) //FaceSides is a struct containing Vector2 values (normals)
            {
                return;
            }

            int faceIndex = (int)parsed * 12;

            for (int i = 0; i < 12; i += 3)
            {
                vertexes.Add(_vertexes[faceIndex + i] + offset.X);
                vertexes.Add(_vertexes[faceIndex + i + 1] + offset.Y);
                vertexes.Add(_vertexes[faceIndex + i + 2] + offset.Z);

                normals.Add(_normals[faceIndex + i]);
                normals.Add(_normals[faceIndex + i + 1]);
                normals.Add(_normals[faceIndex + i + 2]);
            }

            faceIndex = (int)parsed * 8;

            for (int i = 0; i < 8; i += 2)
            {
                uvs.Add(_uvs[faceIndex + i]);
                uvs.Add(_uvs[faceIndex + i + 1]);
            }
        }
Ejemplo n.º 5
0
        public static void AppendFace(Facing side, float[] from, float[] to, Vector3 rotation, Vector3 rotationOrigin,
                                      ref List <float> vertexes, ref List <float> normals)
        {
            FaceSides faceSide = FaceSides.Parse(side); //TextureType parsed to FaceSides, also a normal of this face
            Vector3   normal   = faceSide.ToVec();

            float[] unitFace = _cubeTriangles[faceSide]; //one side of the cube in unit size

            float x = from[0] / 16f;
            float y = from[1] / 16f;
            float z = from[2] / 16f;

            float sx = to[0] / 16f - x; //the size of the cube part
            float sy = to[1] / 16f - y;
            float sz = to[2] / 16f - z;

            for (var i = 0; i < unitFace.Length; i += 3)
            {
                var vertex = RotateVertex(new Vector3(
                                              x + unitFace[i] * sx,
                                              y + unitFace[i + 1] * sy,
                                              z + unitFace[i + 2] * sz), rotation, rotationOrigin);

                vertexes.Add(vertex.X);
                vertexes.Add(vertex.Y);
                vertexes.Add(vertex.Z);

                var nrm = RotateVertex(normal, rotation, rotationOrigin);

                normals.Add(nrm.X);
                normals.Add(nrm.Y);
                normals.Add(nrm.Z);
            }
        }
        public void AppendUvsForSide(FaceSides side, List <float> uvs)
        {
            if (!FaceSides.Parse(side, out var parsed))
            {
                return;
            }

            int faceIndex = (int)parsed * 8;

            for (int i = 0; i < 8; i += 2)
            {
                uvs.Add(_uvs[faceIndex + i]);
                uvs.Add(_uvs[faceIndex + i + 1]);
            }
        }
        //unused for now
        public void AppendNormalsForSide(FaceSides side, List <float> normals)
        {
            if (!FaceSides.Parse(side, out var parsed))
            {
                return;
            }

            int faceIndex = (int)parsed * 12;

            for (int i = 0; i < 12; i += 3)
            {
                normals.Add(_normals[faceIndex + i]);
                normals.Add(_normals[faceIndex + i + 1]);
                normals.Add(_normals[faceIndex + i + 2]);
            }
        }
        public static float[] CreateCubeVertexes(bool centered = false)
        {
            List <float> vertexes = new List <float>();

            void AppendVertexes(TextureType side)
            {
                var face = _cube[FaceSides.Parse(side)];

                for (var index = 0; index < face.Length; index += 3)
                {
                    var x = face[index];
                    var y = face[index + 1];
                    var z = face[index + 2];

                    if (centered)
                    {
                        x -= 0.5f;
                        y -= 0.5f;
                        z -= 0.5f;
                    }

                    vertexes.Add(x);
                    vertexes.Add(y);
                    vertexes.Add(z);
                }
            }

            AppendVertexes(TextureType.up);
            AppendVertexes(TextureType.down);
            AppendVertexes(TextureType.north);
            AppendVertexes(TextureType.south);
            AppendVertexes(TextureType.east);
            AppendVertexes(TextureType.west);

            return(vertexes.ToArray());
        }
Ejemplo n.º 9
0
        public override void Update()
        {
            _ticksLast = _ticks;

            if (OnGround)
            {
                _ticks = (_ticks + 1) % 90;

                if (_ticksLast > _ticks)
                {
                    _ticksLast = _ticks - 1;
                }
            }

            LastPos = Pos;

            Motion.Y -= 0.04f * Gravity;

            Move();

            Motion.Xz *= 0.8664021f;

            List <AxisAlignedBb> bbs = SharpCraft.Instance.World.GetBlockCollisionBoxes(BoundingBox);

            if (bbs.Count > 0)
            {
                BlockPos bp = new BlockPos(Pos);

                FaceSides lastFace     = FaceSides.Up;
                bool      blocksAround = FaceSides.YPlane.All(face => World.IsAir(bp.Offset(lastFace = face))) &&
                                         World.IsAir(bp.Offset(lastFace = FaceSides.Up)) &&
                                         World.IsAir(bp.Offset(lastFace = FaceSides.Down)); //has to be in this order

                if (!blocksAround)
                {
                    Motion += lastFace.ToVec() * 0.1f;
                }
            }

            if (OnGround)
            {
                Motion.Xz *= 0.6676801f;
            }

            if (++_entityAge >= 20 * 50 * 60 + 10) //stay on ground for a minute, 20 ticks as a pick up delay
            {
                SetDead();
                return;
            }

            if (_entityAge < 5)
            {
                return;
            }

            List <EntityItem> inAttractionArea = World.Entities.OfType <EntityItem>().Where(e => e != this && e.IsAlive && e._stack.ItemSame(_stack)).OrderByDescending(e => e._stack.Count).ToList();
            float             attractionRange  = 1.8F;
            float             mergeRange       = 0.15F;

            foreach (EntityItem entity in inAttractionArea)
            {
                if (_stack.IsEmpty || entity._stack.IsEmpty || entity._stack.Count == entity._stack.Item.GetMaxStackSize())
                {
                    continue;
                }

                Vector3 distanceVector = entity.Pos - Pos;
                float   distance       = distanceVector.Length;
                if (distance >= attractionRange)
                {
                    continue;
                }

                int ammountToTake = Math.Min(_stack.Item.GetMaxStackSize() - _stack.Count, entity._stack.Count);
                if (ammountToTake == 0)
                {
                    continue;
                }

                if (distance <= mergeRange)
                {
                    //Motion -= entity.Motion * MathUtil.Remap(entity.stack.Count / (float)stack.Count, 1, 64, 1, 3);
                    //entity.Motion -= Motion * MathUtil.Remap(stack.Count / (float)entity.stack.Count, 1, 64, 1, 3);

                    entity._stack.Count -= ammountToTake;
                    if (entity._stack.IsEmpty)
                    {
                        entity.SetDead();
                    }
                    _stack.Count += ammountToTake;

                    _entityAge        = 3;
                    entity._entityAge = 1;
                    continue;
                }

                distanceVector.Normalize();

                float distanceMul = (float)Math.Sqrt(1 - distance / attractionRange);
                if (distanceMul > 0.8)
                {
                    distanceMul = ((1 - distanceMul) / 0.2F) * 0.6F + 0.2F;
                }
                Vector3 baseForce = distanceVector * 0.02f * distanceMul * MathUtil.Remap(_stack.Count / (float)entity._stack.Count, 1, entity._stack.Item.GetMaxStackSize(), 2, 5);

                Motion        += baseForce * entity._stack.Count / Math.Max(entity._stack.Count, _stack.Count);
                entity.Motion -= baseForce * _stack.Count / Math.Max(entity._stack.Count, _stack.Count);
            }

            if (_entityAge < 15 || !IsAlive)
            {
                return;
            }

            //TODO change this for multiplayer
            IEnumerable <EntityPlayerSp> players = World.Entities.OfType <EntityPlayerSp>()
                                                   .OrderBy(entity => Vector3.Distance(entity.Pos, Pos))
                                                   .Where(e => Vector3.Distance(e.Pos, Pos) <= attractionRange);

            foreach (EntityPlayerSp player in players)
            {
                if (!player.CanPickUpStack(_stack))
                {
                    continue;
                }

                Vector3 attrTarget = player.Pos;
                attrTarget.Y += player.GetCollisionBoundingBox().Size.Y / 2;

                Vector3 distanceVector = attrTarget - Pos;

                if (distanceVector.Length <= 0.35f)
                {
                    if (player.OnPickup(_stack))
                    {
                        SetDead();
                    }

                    Motion *= -1f;
                }

                Motion = distanceVector.Normalized() * 0.45f;
            }
            if (_stack.IsEmpty)
            {
                SetDead();
            }
        }
        public ParticleDigging(World world, Vector3 pos, Vector3 motion, float particleScale, BlockState state, FaceSides side) : base(world, pos, motion, particleScale, JsonModelLoader.TEXTURE_BLOCKS)
        {
            State = state;

            ModelBlock model = JsonModelLoader.GetModelForBlock(state.Block.UnlocalizedName);

            if (model.RawModel is ModelBlockRaw mbr)
            {
                Vector2 start;
                Vector2 end;

                if (state.Block.IsFullCube)
                {
                    List <float> uvs = new List <float>(8);
                    mbr.AppendUvsForSide(side, uvs);

                    start = new Vector2(uvs[0], uvs[1]);
                    end   = new Vector2(uvs[4], uvs[5]); //4,5 because that's the 3. vertex and the local UV there is 1,1
                }
                else
                {
                    var tex = model.GetParticleTexture();

                    start = tex.UVMin;
                    end   = tex.UVMax;
                }

                Vector2 size = end - start;

                Vector2 pixel = size / 16;

                UVmin = start + pixel * new Vector2(MathUtil.NextFloat(0, 12), MathUtil.NextFloat(0, 12));
                UVmax = UVmin + pixel * 4;
            }

            if (side == FaceSides.Up)
            {
                Motion.Xz = SharpCraft.Instance.Camera.GetLookVec().Xz * 0.15f;
            }

            Vector3 vec = new Vector3(MathUtil.NextFloat(-1), MathUtil.NextFloat(-1), MathUtil.NextFloat(-1));

            _rotStep = vec.Normalized() * MathUtil.NextFloat(40, 75);
        }
Ejemplo n.º 11
0
        public void GetMouseOverObject()
        {
            if (World == null)
            {
                return;
            }

            float radius = 5.5f;

            MouseOverObject final = new MouseOverObject();

            float dist = float.MaxValue;

            Vector3 camPos = Vector3.One * 0.5f + Camera.Pos;

            var air = BlockRegistry.GetBlock <BlockAir>();

            for (float z = -radius; z <= radius; z++)
            {
                for (float y = -radius; y <= radius; y++)
                {
                    for (float x = -radius; x <= radius; x++)
                    {
                        Vector3 vec = camPos;
                        vec.X += x;
                        vec.Y += y;
                        vec.Z += z;

                        float f = (vec - Camera.Pos).LengthFast;

                        if (f <= radius + 0.5f)
                        {
                            BlockPos   pos   = new BlockPos(vec);
                            BlockState state = World.GetBlockState(pos);

                            if (state.Block != air)
                            {
                                AxisAlignedBb bb = state.Block.BoundingBox.Offset(pos.ToVec());

                                bool hitSomething = RayHelper.RayIntersectsBB(Camera.Pos,
                                                                              Camera.GetLookVec(), bb, out Vector3 hitPos, out Vector3 normal);

                                if (hitSomething)
                                {
                                    FaceSides sideHit = FaceSides.Null;

                                    if (normal.X < 0)
                                    {
                                        sideHit = FaceSides.West;
                                    }
                                    else if (normal.X > 0)
                                    {
                                        sideHit = FaceSides.East;
                                    }
                                    if (normal.Y < 0)
                                    {
                                        sideHit = FaceSides.Down;
                                    }
                                    else if (normal.Y > 0)
                                    {
                                        sideHit = FaceSides.Up;
                                    }
                                    if (normal.Z < 0)
                                    {
                                        sideHit = FaceSides.North;
                                    }
                                    else if (normal.Z > 0)
                                    {
                                        sideHit = FaceSides.South;
                                    }

                                    BlockPos p = new BlockPos(hitPos - normal * bb.Size / 2);

                                    if (sideHit == FaceSides.Null)
                                    {
                                        continue;
                                    }

                                    float l = Math.Abs((Camera.Pos - (p.ToVec() + bb.Size / 2)).Length);

                                    if (l < dist)
                                    {
                                        dist = l;

                                        final.hit      = HitType.Block;
                                        final.hitVec   = hitPos;
                                        final.blockPos = p;
                                        final.normal   = normal;
                                        final.sideHit  = sideHit;

                                        final.boundingBox = bb;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            MouseOverObject = final;
        }
Ejemplo n.º 12
0
        public void BuildChunkModelNow()
        {
            if (ModelBuilding || !QueuedForModelBuild)
            {
                return;
            }

            ModelBuilding = true;

            //ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>> modelRaw = new ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>>();

            //List<RawQuad> quads;

            Stopwatch sw = Stopwatch.StartNew(); //this is just a debug thing....

            var air = BlockRegistry.GetBlock <BlockAir>();

            var vertexes = new List <float>();
            var normals  = new List <float>();
            var uvs      = new List <float>();

            object locker = new object();

            //generate the model - fill MODEL_RAW
            Enumerable.Range(0, ChunkHeight).AsParallel().ForAll(y =>
            {
                for (int x = 0; x < ChunkSize; x++)
                {
                    for (int z = 0; z < ChunkSize; z++)
                    {
                        BlockPos worldPos = new BlockPos(x + Pos.WorldSpaceX(), y, z + Pos.WorldSpaceZ());

                        BlockState state = World.GetBlockState(worldPos);
                        if (state.Block == air)
                        {
                            continue;
                        }

                        BlockPos localPos = new BlockPos(x, y, z);

                        ModelBlockRaw mbr = (ModelBlockRaw)state.Model?.RawModel;

                        if (mbr == null)
                        {
                            continue;
                        }

                        if (!state.Block.IsFullCube)
                        {
                            lock (locker)
                                mbr.AppendAllVertexData(vertexes, normals, uvs, localPos);

                            continue;
                        }

                        for (var index = 0; index < FaceSides.AllSides.Count; index++)
                        {
                            FaceSides dir = FaceSides.AllSides[index];

                            BlockPos worldPosO = worldPos.Offset(dir);
                            BlockState stateO  = World.GetBlockState(worldPosO);

                            if (!(stateO.Block == air ||
                                  stateO.Block.HasTransparency && !state.Block.HasTransparency) &&
                                stateO.Block.IsFullCube)
                            {
                                continue;
                            }

                            lock (locker)
                            {
                                mbr.AppendVertexDataForSide(dir, vertexes, normals, uvs, localPos);
                                //mbr.AppendNormalsForSide(dir, normals);
                                //mbr.AppendUvsForSide(dir, uvs);
                            }
                        }
                    }
                }
            });

            sw.Stop();
            Console.WriteLine($"DEBUG: built chunk model [{sw.Elapsed.TotalMilliseconds:F}ms]");

            float[] vtx = vertexes.ToArray(); //this is here because this takes time and I don't want it to slow down the main thread by running it in GlContext
            float[] nrm = normals.ToArray();
            float[] uv  = uvs.ToArray();

            SharpCraft.Instance.RunGlContext(() =>
            {
                if (_model == null)
                {
                    _model = new ModelChunk(vtx, nrm, uv, Block.DefaultShader);
                }
                else
                {
                    _model.OverrideData(vtx, nrm, uv);
                }

                ModelBuilding = false;
            });

            QueuedForModelBuild = false;
        }
Ejemplo n.º 13
0
        public ParticleDigging(World world, Vector3 pos, Vector3 motion, float particleScale, BlockState state, FaceSides side) : base(world, pos, motion, particleScale, JsonModelLoader.TextureBlocks)
        {
            State = state;

            if (state.Model.RawModel is ModelBlockRaw)
            {
                var tex = state.Model.ParticleTexture;

                Vector2 start = tex.UVMin;
                Vector2 end   = tex.UVMax;

                Vector2 size = end - start;

                Vector2 pixel = size / 16;

                UVmin = start + pixel * new Vector2(MathUtil.NextFloat(0, 12), MathUtil.NextFloat(0, 12));
                UVmax = UVmin + pixel * 4;
            }

            if (side == FaceSides.Up)
            {
                Motion.Xz = SharpCraft.Instance.Camera.GetLookVec().Xz * 0.15f;
            }

            Vector3 vec = new Vector3(MathUtil.NextFloat(-1), MathUtil.NextFloat(-1), MathUtil.NextFloat(-1));

            _rotStep = vec.Normalized() * MathUtil.NextFloat(40, 75);
        }