public void updateFromPoint(ClothPoint point, IWorldAccessor world) { PointIndex = point.PointIndex; Mass = point.Mass; InvMass = point.InvMass; Pos.Set(point.Pos); Velocity.Set(point.Pos); Tension.Set(point.Tension); GravityStrength = point.GravityStrength; pinned = point.pinned; pinnedToEntityId = point.pinnedToEntityId; if (pinnedToEntityId != 0) { pinnedTo = world.GetEntityById(pinnedToEntityId); if (pinnedTo != null) { PinTo(pinnedTo, pinnedToOffset); } else { UnPin(); } } pinnedToBlockPos = pinnedToBlockPos.SetOrCreate(point.pinnedToBlockPos); pinnedToOffset = pinnedToOffset.SetOrCreate(point.pinnedToOffset); pinnedToOffsetStartYaw = point.pinnedToOffsetStartYaw; }
public void RestorePoints(Dictionary <int, ClothPoint> pointsByIndex) { p1 = pointsByIndex[PointIndex1]; p2 = pointsByIndex[PointIndex2]; rest_length = GameMath.Sqrt(squared_rest_length); inverse_length = 1f / rest_length; renderCenterPos = p1.Pos + (p1.Pos - p2.Pos) / 2; }
public void Attach(ClothSystem sys, ClothPoint point) { if (!entity.WatchedAttributes.HasAttribute("clothIds")) { entity.WatchedAttributes["clothIds"] = new IntArrayAttribute(new int[] { sys.ClothId }); } ClothIds.AddInt(sys.ClothId); point.PinTo(entity, new Vec3f(0, 0.5f, 0)); }
private void attachToBlock(EntityAgent byEntity, BlockPos toPosition, ClothSystem sys, ItemSlot slot) { var pEnds = sys.Ends; // 2 possible cases // - We just created a new rope: use pEnds[1] because its unattached // - We already have both ends attached and want to re-attach the player held end ClothPoint cpoint = pEnds[0].PinnedToEntity?.EntityId == byEntity.EntityId && pEnds[1].Pinned ? pEnds[0] : pEnds[1]; cpoint.PinTo(toPosition, new Vec3f(0.5f, 0.5f, 0.5f)); }
public ClothConstraint(ClothPoint p1, ClothPoint p2) { this.p1 = p1; this.p2 = p2; PointIndex1 = p1.PointIndex; PointIndex2 = p2.PointIndex; squared_rest_length = p1.Pos.SquareDistanceTo(p2.Pos); rest_length = GameMath.Sqrt(squared_rest_length); inverse_length = 1f / rest_length; renderCenterPos = p1.Pos + (p1.Pos - p2.Pos) / 2; }
public void CustomRender(float dt) { if (LineDebug && capi != null) { BlockPos originPos = CenterPosition.AsBlockPos; for (int i = 0; i < Constraints.Count; i++) { ClothPoint p1 = Constraints[i].Point1; ClothPoint p2 = Constraints[i].Point2; debugUpdateMesh.xyz[i * 6 + 0] = (float)(p1.Pos.X - originPos.X); debugUpdateMesh.xyz[i * 6 + 1] = (float)(p1.Pos.Y - originPos.Y) + 0.005f; debugUpdateMesh.xyz[i * 6 + 2] = (float)(p1.Pos.Z - originPos.Z); debugUpdateMesh.xyz[i * 6 + 3] = (float)(p2.Pos.X - originPos.X); debugUpdateMesh.xyz[i * 6 + 4] = (float)(p2.Pos.Y - originPos.Y) + 0.005f; debugUpdateMesh.xyz[i * 6 + 5] = (float)(p2.Pos.Z - originPos.Z); } capi.Render.UpdateMesh(debugMeshRef, debugUpdateMesh); IShaderProgram prog = capi.Shader.GetProgram((int)EnumShaderProgram.Autocamera); prog.Use(); capi.Render.LineWidth = 6; capi.Render.BindTexture2d(0); capi.Render.GLDisableDepthTest(); Vec3d cameraPos = capi.World.Player.Entity.CameraPos; mat.Set(capi.Render.CameraMatrixOrigin); mat.Translate( (float)(originPos.X - cameraPos.X), (float)(originPos.Y - cameraPos.Y), (float)(originPos.Z - cameraPos.Z) ); prog.UniformMatrix("projectionMatrix", capi.Render.CurrentProjectionMatrix); prog.UniformMatrix("modelViewMatrix", mat.Values); capi.Render.RenderMesh(debugMeshRef); prog.Stop(); capi.Render.GLEnableDepthTest(); } }
private void attachToEntity(EntityAgent byEntity, Entity toEntity, ClothSystem sys, ItemSlot slot) { if (!toEntity.HasBehavior <EntityBehaviorRopeTieable>()) { if (api.World.Side == EnumAppSide.Client) { (api as ICoreClientAPI).TriggerIngameError(this, "notattachable", Lang.Get("This creature is not tieable")); } return; } var pEnds = sys.Ends; ClothPoint cpoint = pEnds[0].PinnedToEntity?.EntityId == byEntity.EntityId && pEnds[1].Pinned ? pEnds[0] : pEnds[1]; toEntity.GetBehavior <EntityBehaviorRopeTieable>().Attach(sys, cpoint); }
public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel, ref EnumHandling handling) { ClothSystem cs = cm.GetClothSystemAttachedToBlock(blockSel.Position); if (cs != null) { Entity byEntity = byPlayer.Entity; ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot; Vec3d lpos = new Vec3d(0, byEntity.LocalEyePos.Y - 0.25f, 0); Vec3d aheadPos = lpos.AheadCopy(0.25f, byEntity.SidedPos.Pitch, byEntity.SidedPos.Yaw); // Already handled by ItemRope if (!slot.Empty && slot.Itemstack.Collectible.Code.Path == "rope" && (cs.FirstPoint.PinnedToEntity?.EntityId == byPlayer.Entity.EntityId || cs.LastPoint.PinnedToEntity?.EntityId == byPlayer.Entity.EntityId)) { return(base.OnBlockInteractStart(world, byPlayer, blockSel, ref handling)); } ClothPoint targetPoint = cs.FirstPoint.PinnedToBlockPos == blockSel.Position ? cs.FirstPoint : cs.LastPoint; ItemStack stack = new ItemStack(world.GetItem(new AssetLocation("rope"))); stack.Attributes.SetInt("clothId", cs.ClothId); stack.Attributes.SetLong("ropeHeldByEntityId", byEntity.EntityId); if (byPlayer.InventoryManager.TryGiveItemstack(stack, true)) { targetPoint.PinTo(byPlayer.Entity, aheadPos.ToVec3f()); } else { Entity ei = world.SpawnItemEntity(stack, blockSel.Position.ToVec3d().Add(0.5, 0.5, 0.5)); targetPoint.PinTo(ei, new Vec3f(0, 0.1f, 0)); } handling = EnumHandling.PreventDefault; return(true); } return(base.OnBlockInteractStart(world, byPlayer, blockSel, ref handling)); }
public override void OnCollected(ItemStack stack, Entity entity) { int clothId = stack.Attributes.GetInt("clothId"); if (clothId != 0) { ClothSystem sys = cm.GetClothSystem(clothId); if (sys != null) { ClothPoint p = null; if (sys.FirstPoint.PinnedToEntity is EntityItem) { p = sys.FirstPoint; } if (sys.LastPoint.PinnedToEntity is EntityItem) { p = sys.LastPoint; } if (p != null) { Vec3d lpos = new Vec3d(0, entity.LocalEyePos.Y - 0.3f, 0); Vec3d aheadPos = lpos.AheadCopy(0.1f, entity.SidedPos.Pitch, entity.SidedPos.Yaw).AheadCopy(0.4f, entity.SidedPos.Pitch, entity.SidedPos.Yaw - GameMath.PIHALF); p.PinTo(entity, aheadPos.ToVec3f()); ItemSlot collectedSlot = null; (entity as EntityPlayer).WalkInventory((slot) => { if (!slot.Empty && slot.Itemstack.Attributes.GetInt("clothId") == clothId) { collectedSlot = slot; return(false); } return(true); }); collectedSlot?.Itemstack?.Attributes.SetLong("ropeHeldByEntityId", entity.EntityId); collectedSlot?.MarkDirty(); } } } }
public override void OnGroundIdle(EntityItem entityItem) { long ropeHeldByEntityId = entityItem.Itemstack.Attributes.GetLong("ropeHeldByEntityId"); if (ropeHeldByEntityId != 0) { entityItem.Itemstack.Attributes.RemoveAttribute("ropeHeldByEntityId"); int clothId = entityItem.Itemstack.Attributes.GetInt("clothId"); if (clothId != 0) { // Console.WriteLine(api.World.Side + ", clothid {0}, dropped on ground.", clothId); ClothSystem sys = cm.GetClothSystem(clothId); if (sys != null) { ClothPoint p = null; if (sys.FirstPoint.PinnedToEntity?.EntityId == ropeHeldByEntityId) { p = sys.FirstPoint; } if (sys.LastPoint.PinnedToEntity?.EntityId == ropeHeldByEntityId) { p = sys.LastPoint; } if (p != null) { // Console.WriteLine(api.World.Side + ", clothid {0}, dropped on ground, now pinned to dropped item.", clothId); p.PinTo(entityItem, new Vec3f(entityItem.SelectionBox.X2 / 2, entityItem.SelectionBox.Y2 / 2, entityItem.SelectionBox.Z2 / 2)); } } } } }
public void updatePoint(ClothPointPacket msg) { ClothPoint point = Points2d[msg.PointX].Points[msg.PointY]; point.updateFromPoint(msg.Point, api.World); }
private ClothSystem(ICoreAPI api, ClothManager cm, BlockPos originPos, float xsize, float zsize, EnumClothType clothType, AssetLocation ropeSectionModel = null) { this.clothType = clothType; this.ropeSectionModel = ropeSectionModel; Init(api, cm); Random rand = api.World.Rand; bool hor = rand.NextDouble() < 0.5; int vertexIndex = 0; float step = 1 / Resolution; int numzpoints = (int)Math.Round(zsize * Resolution); int numxpoints = (int)Math.Round(xsize * Resolution); if (clothType == EnumClothType.Rope) { numzpoints = 1; } float roughness = 0.05f; int k = 0; int pointIndex = 0; for (int z = 0; z < numzpoints; z++) { Points2d.Add(new PointList()); for (int x = 0; x < numxpoints; x++) { float dx = x * step; float dy = z * step; float dz = -roughness / 2 + (float)rand.NextDouble() * roughness; if (hor) { dx = x * step; dy = -roughness / 2 + (float)rand.NextDouble() * roughness; dz = z * step; } var point = new ClothPoint(this, pointIndex++, originPos.X + dx, originPos.Y + dy, originPos.Z + dz); Points2d[z].Points.Add(point); int color = (k++ % 2) > 0 ? ColorUtil.WhiteArgb : ColorUtil.BlackArgb; // add a vertical constraint if (z > 0) { ClothPoint p1 = Points2d[z - 1].Points[x]; ClothPoint p2 = Points2d[z].Points[x]; var constraint = new ClothConstraint(p1, p2); Constraints.Add(constraint); if (capi != null) { if (LineDebug) { debugUpdateMesh.AddVertex(0, 0, 0, color); debugUpdateMesh.AddVertex(0, 0, 0, color); debugUpdateMesh.AddIndex(vertexIndex++); debugUpdateMesh.AddIndex(vertexIndex++); } } } // add a new horizontal constraints if (x > 0) { ClothPoint p1 = Points2d[z].Points[x - 1]; ClothPoint p2 = Points2d[z].Points[x]; var constraint = new ClothConstraint(p1, p2); Constraints.Add(constraint); if (capi != null) { if (LineDebug) { debugUpdateMesh.AddVertex(0, 0, 0, color); debugUpdateMesh.AddVertex(0, 0, 0, color); debugUpdateMesh.AddIndex(vertexIndex++); debugUpdateMesh.AddIndex(vertexIndex++); } } } } } if (capi != null && LineDebug) { debugUpdateMesh.mode = EnumDrawMode.Lines; debugMeshRef = capi.Render.UploadMesh(debugUpdateMesh); debugUpdateMesh.Indices = null; debugUpdateMesh.Rgba = null; } }