public void BreakBlock()
        {
            MouseOverObject moo = SharpCraft.Instance.MouseOverObject;

            if (moo.hit != HitType.Block)
            {
                return;
            }

            BlockState state = World.GetBlockState(moo.blockPos);

            if (JsonModelLoader.GetModelForBlock(state.Block.UnlocalizedName) != null)
            {
                SharpCraft.Instance.ParticleRenderer.SpawnDestroyParticles(moo.blockPos, state);
            }

            World.SetBlockState(moo.blockPos, BlockRegistry.GetBlock <BlockAir>().GetState());

            Vector3 motion = new Vector3(MathUtil.NextFloat(-0.15f, 0.15f), 0.3f, MathUtil.NextFloat(-0.15f, 0.15f));

            EntityItem entityDrop = new EntityItem(World, moo.blockPos.ToVec() + Vector3.One * 0.5f, motion, new ItemStack(new ItemBlock(state.Block), 1, state.Block.GetMetaFromState(state)));

            World.AddEntity(entityDrop);

            SharpCraft.Instance.GetMouseOverObject();
        }
Exemple #2
0
        public void RegisterBlocksPost(JsonModelLoader loader)
        {
            Block.SetDefaultShader(new Shader <ModelBlock>("block"));

            foreach (var pair in _registry)
            {
                pair.Value.RegisterState(loader,
                                         new BlockState(pair.Value, JsonModelLoader.GetModelForBlock(pair.Key)));
            }
        }
        protected virtual void RenderBlock(Block block, float x, float y, float scale)
        {
            var model = JsonModelLoader.GetModelForBlock(block.UnlocalizedName);

            if (model == null)
            {
                return;
            }

            ModelBlockRaw mbr = (ModelBlockRaw)model.RawModel;
            List <float>  uvs = new List <float>(8);

            mbr.AppendUvsForSide(FaceSides.South, uvs);

            Vector2 UVmin = new Vector2(uvs[0], uvs[1]);
            Vector2 UVmax = new Vector2(uvs[4], uvs[5]);

            Vector2 unit = new Vector2(1f / SharpCraft.Instance.ClientSize.Width, 1f / SharpCraft.Instance.ClientSize.Height);

            float width  = 16;
            float height = 16;

            float scaledWidth  = 16 * scale;
            float scaledHeight = 16 * scale;

            float posX = x + scaledWidth / 2;
            float posY = -y - scaledHeight / 2;

            Vector2 pos = new Vector2(posX, posY).Ceiling() * unit;

            Matrix4 mat = MatrixHelper.CreateTransformationMatrix(pos * 2 - Vector2.UnitX + Vector2.UnitY, scale * new Vector2(width, height) * unit);

            _item.Bind();

            Shader.Bind();
            Shader.UpdateGlobalUniforms();
            Shader.UpdateModelUniforms();
            Shader.UpdateInstanceUniforms(mat, UVmin, UVmax);

            GL.BindTexture(TextureTarget.Texture2D, JsonModelLoader.TEXTURE_BLOCKS);
            _item.RawModel.Render(PrimitiveType.Quads);

            _item.Unbind();
        }
        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);
        }
Exemple #5
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);

                        ModelBlock model  = JsonModelLoader.GetModelForBlock(state.Block.UnlocalizedName);
                        ModelBlockRaw mbr = (ModelBlockRaw)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;
        }
Exemple #6
0
        public override void Render(float partialTicks)
        {
            Vector3 partialPos  = LastPos + (Pos - LastPos) * partialTicks;
            float   partialTime = tick + partialTicks;

            if (stack?.Item is ItemBlock itemBlock)
            {
                ModelBlock model = JsonModelLoader.GetModelForBlock(itemBlock.Block.UnlocalizedName);

                if (model == null || model.RawModel == null)
                {
                    return;
                }

                float time = onGround ? (float)((Math.Sin(partialTime / 8) + 1) / 16) : 0;

                _shader.Bind();

                GL.BindVertexArray(model.RawModel.VaoID);

                GL.EnableVertexAttribArray(0);
                GL.EnableVertexAttribArray(1);
                GL.EnableVertexAttribArray(2);

                GL.BindTexture(TextureTarget.Texture2D, JsonModelLoader.TEXTURE_BLOCKS);

                int itemsToRender = 1;

                if (stack.Count > 1)
                {
                    itemsToRender = 2;
                }
                if (stack.Count >= 32 * 4)
                {
                    itemsToRender = 3;
                }
                if (stack.Count == 64 * 4)
                {
                    itemsToRender = 4;
                }

                for (int i = 0; i < itemsToRender; i++)
                {
                    Vector3 rot   = Vector3.UnitY * partialTime * 3;
                    Vector3 pos   = partialPos - (Vector3.UnitX * 0.125f + Vector3.UnitZ * 0.125f) + Vector3.UnitY * time;
                    Vector3 pos_o = Vector3.One * (i / 8f);

                    Matrix4 x = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(rot.X));
                    Matrix4 y = Matrix4.CreateRotationY(MathHelper.DegreesToRadians(rot.Y));
                    Matrix4 z = Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(rot.Z));

                    Vector3 vec = Vector3.One * 0.5f;

                    Matrix4 s  = Matrix4.CreateScale(0.25f);
                    Matrix4 t  = Matrix4.CreateTranslation(pos + vec * 0.25f);
                    Matrix4 t2 = Matrix4.CreateTranslation(-vec);
                    Matrix4 t3 = Matrix4.CreateTranslation(pos_o);

                    Matrix4 mat = t3 * t2 * (z * y * x * s) * t;

                    _shader.UpdateGlobalUniforms();
                    _shader.UpdateModelUniforms(model.RawModel);
                    _shader.UpdateInstanceUniforms(mat, this);
                    model.RawModel.Render(PrimitiveType.Quads);
                }

                GL.BindVertexArray(0);

                GL.DisableVertexAttribArray(0);
                GL.DisableVertexAttribArray(1);
                GL.DisableVertexAttribArray(2);

                _shader.Unbind();
            }
        }
        public void SpawnDiggingParticle(MouseOverObject moo)
        {
            if (moo.hit == HitType.Block)
            {
                var state = SharpCraft.Instance.World.GetBlockState(moo.blockPos);

                if (JsonModelLoader.GetModelForBlock(state.Block.UnlocalizedName) == null)
                {
                    return;
                }

                float f0 = moo.hitVec.X
                           + MathUtil.NextFloat(-0.21f, 0.21f) * Math.Abs(moo.boundingBox.max.X - moo.boundingBox.min.X);
                float f1 = moo.hitVec.Y
                           + MathUtil.NextFloat(0, 0.1f) * Math.Abs(moo.boundingBox.max.Y - moo.boundingBox.min.Y);
                float f2 = moo.hitVec.Z
                           + MathUtil.NextFloat(-0.21f, 0.21f) * Math.Abs(moo.boundingBox.max.Z - moo.boundingBox.min.Z);

                if (moo.sideHit == FaceSides.Down)
                {
                    f1 = moo.boundingBox.min.Y - 0.05f;
                }
                else if (moo.sideHit == FaceSides.East)
                {
                    f0 = moo.boundingBox.max.X + 0.05f;
                }
                else if (moo.sideHit == FaceSides.North)
                {
                    f2 = moo.boundingBox.min.Z - 0.05f;
                }
                else if (moo.sideHit == FaceSides.South)
                {
                    f2 = moo.boundingBox.max.Z + 0.05f;
                }
                else if (moo.sideHit == FaceSides.Up)
                {
                    f1 = moo.boundingBox.max.Y + 0.1f;
                }
                else if (moo.sideHit == FaceSides.West)
                {
                    f0 = moo.boundingBox.min.X - 0.05f;
                }

                Vector3 pos = new Vector3(f0, f1, f2) + moo.normal * 0.1f;

                Vector3 motion = moo.normal * MathUtil.NextFloat(0.0075f, 0.03f);
                float   mult   = 0.75f / (MathUtil.Distance(pos, moo.hitVec) + 0.01f);
                motion.Xz *= mult;

                motion.Y += 0.02f;

                bool ok = SharpCraft.Instance.DestroyProgresses.TryGetValue(moo.blockPos, out DestroyProgress progress);

                AddParticle(new ParticleDigging(
                                SharpCraft.Instance.World,
                                pos,
                                motion,
                                0.35f + (ok ? progress.PartialProgress * 0.5f : 0),
                                state,
                                moo.sideHit));
            }
        }