From fec95dd41443917090418ce0081d3bb55d50920d Mon Sep 17 00:00:00 2001
From: CXUtk <2237367067@qq.com>
Date: Thu, 29 Jun 2023 22:08:32 -0700
Subject: [PATCH 01/13] initial upload
---
Localization/en-US_Mods.Everglow.hjson | 3058 +++++++++++++++++
Sources/Everglow.Core/Everglow.Core.csproj | 11 +
.../Physics/PBEngine/Collision/AABB.cs | 20 +
.../Collision/BroadPhase/BruteForceDetect.cs | 115 +
.../Collision/BroadPhase/CollisionGraph.cs | 65 +
.../Collision/BroadPhase/IBroadPhase.cs | 24 +
.../Collision/BroadPhase/SweepAndPrune.cs | 143 +
.../Collision/Colliders/BoxCollider.cs | 489 +++
.../Collision/Colliders/Collider2D.cs | 37 +
.../Collision/Colliders/SphereCollider.cs | 201 ++
.../PBEngine/Collision/CollisionEvent2D.cs | 65 +
.../PBEngine/Collision/CollisionInfo.cs | 20 +
.../Physics/PBEngine/Collision/Edge2D.cs | 66 +
.../PBEngine/Collision/ImpluseEntry.cs | 18 +
.../PBEngine/Collision/MovementType.cs | 31 +
.../Physics/PBEngine/Constrains/Constrain.cs | 15 +
.../PBEngine/Constrains/JointConstrain.cs | 63 +
.../PBEngine/Constrains/SpringConstrain.cs | 96 +
.../PBEngine/GameInteraction/TileCollider.cs | 55 +
.../GameInteraction/TileCollisionUtils.cs | 300 ++
.../Physics/PBEngine/GeometryUtils.cs | 401 +++
.../Physics/PBEngine/PhysicsObject.cs | 162 +
.../Physics/PBEngine/PhysicsSimulation.cs | 229 ++
.../PlayGround/Constrain/JointPlayground.cs | 229 ++
.../PlayGround/Contact/ContactPlayGround1.cs | 308 ++
.../PlayGround/Contact/ContactPlayGround2.cs | 110 +
.../Physics/PBEngine/RigidBody2D.cs | 584 ++++
.../Physics/PBEngine/Shaders/Default.fx | 43 +
Sources/Everglow.Core/Utilities/Matrix2x2.cs | 210 ++
Sources/Everglow.Core/Utilities/Matrix3x3.cs | 217 ++
Sources/Everglow.Core/Utilities/Utils.md | 8 +-
Sources/Modules/Example/RigidBodyDisplay.cs | 97 +
32 files changed, 7489 insertions(+), 1 deletion(-)
create mode 100644 Localization/en-US_Mods.Everglow.hjson
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/IBroadPhase.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/SweepAndPrune.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/BoxCollider.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/Collider2D.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/SphereCollider.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionEvent2D.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionInfo.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/Edge2D.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/ImpluseEntry.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/MovementType.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Constrains/Constrain.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Constrains/JointConstrain.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollider.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollisionUtils.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/GeometryUtils.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/PhysicsObject.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/PlayGround/Constrain/JointPlayground.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround1.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround2.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Shaders/Default.fx
create mode 100644 Sources/Everglow.Core/Utilities/Matrix2x2.cs
create mode 100644 Sources/Everglow.Core/Utilities/Matrix3x3.cs
create mode 100644 Sources/Modules/Example/RigidBodyDisplay.cs
diff --git a/Localization/en-US_Mods.Everglow.hjson b/Localization/en-US_Mods.Everglow.hjson
new file mode 100644
index 000000000..efc8c0216
--- /dev/null
+++ b/Localization/en-US_Mods.Everglow.hjson
@@ -0,0 +1,3058 @@
+Tiles: {
+ BottleOfNutShellFlowers.MapEntry: Bottle Of Nut Shell Flowers
+ PlumBlossomInABowl.MapEntry: Plum Blossom In A Bowl
+ WhiteLotusBonsai.MapEntry: White Lotus Bonsai
+ BloodifyPlatform.MapEntry: Bloodify Platform
+ BloodyMossWheel.MapEntry: Bloody Moss Wheel
+ BloodyMossWheelFinished.MapEntry: Bloody Moss Wheel Finished
+ StoneTusk.MapEntry: Stone Tusk
+ StoneTuskSmall.MapEntry: Stone Tusk Small
+ StrangeTuskStone.MapEntry: Strange Tusk Stone
+ StrangeTuskStone1.MapEntry: Strange Tusk Stone1
+ StrangeTuskStone2.MapEntry: Strange Tusk Stone2
+ StrangeTuskStone3.MapEntry: Strange Tusk Stone3
+ StrangeTuskStone4.MapEntry: Strange Tusk Stone4
+ TuskRelic.MapEntry: Tusk Relic
+ BlackFren.MapEntry: Black Fren
+ BlackFrenLarge.MapEntry: Black Fren Large
+ BlackStarShrub.MapEntry: Black Star Shrub
+ BlackStarShrubSmall.MapEntry: Black Star Shrub Small
+ BlackVine.MapEntry: Black Vine
+ BlueBlossom.MapEntry: Blue Blossom
+ CocoonRock.MapEntry: Cocoon Rock
+ GlowingReed.MapEntry: Glowing Reed
+ LampLotus.MapEntry: Lamp Lotus
+ MothWorldDoor.MapEntry: Moth World Door
+ CyanVineBar.MapEntry: Cyan Vine Bar
+ CyanVineOreTile.MapEntry: Cyan Vine Ore Tile
+ CyanVineStone.MapEntry: Cyan Vine Stone
+ LiftLamp.MapEntry: Lift Lamp
+}
+
+Biomes: {
+ TuskBiome: {
+ DisplayName: Tusk Biome
+ TownNPCDialogueName: the Tusk Biome
+ }
+
+ TuskSurfaceBiome: {
+ DisplayName: Tusk Surface Biome
+ TownNPCDialogueName: the Tusk Surface Biome
+ }
+
+ FireflyBiome: {
+ DisplayName: Firefly Biome
+ TownNPCDialogueName: the Firefly Biome
+ }
+
+ YggdrasilTownBiome: {
+ DisplayName: Yggdrasil Town Biome
+ TownNPCDialogueName: the Yggdrasil Town Biome
+ }
+
+ KelpCurtainBiome: {
+ DisplayName: Kelp Curtain Biome
+ TownNPCDialogueName: the Kelp Curtain Biome
+ }
+}
+
+MapEntry.FluorescentTree: Mods.Everglow.MapEntry.FluorescentTree
+
+Buffs: {
+ BloodSwordStrikeBuff: {
+ DisplayName: Blood Sword Strike Buff
+ Description: Mods.Everglow.Buffs.BloodSwordStrikeBuff.Description
+ }
+
+ LifeRotten: {
+ DisplayName: Life Rotten
+ Description: Mods.Everglow.Buffs.LifeRotten.Description
+ }
+
+ OnElectric: {
+ DisplayName: On Electric
+ Description: Mods.Everglow.Buffs.OnElectric.Description
+ }
+
+ StarCrack: {
+ DisplayName: Star Crack
+ Description: Mods.Everglow.Buffs.StarCrack.Description
+ }
+
+ AppleBuff: {
+ DisplayName: Apple Buff
+ Description: Mods.Everglow.Buffs.AppleBuff.Description
+ }
+
+ ApplePieBuff: {
+ DisplayName: Apple Pie Buff
+ Description: Mods.Everglow.Buffs.ApplePieBuff.Description
+ }
+
+ ApricotBuff: {
+ DisplayName: Apricot Buff
+ Description: Mods.Everglow.Buffs.ApricotBuff.Description
+ }
+
+ BaconBuff: {
+ DisplayName: Bacon Buff
+ Description: Mods.Everglow.Buffs.BaconBuff.Description
+ }
+
+ BananaBuff: {
+ DisplayName: Banana Buff
+ Description: Mods.Everglow.Buffs.BananaBuff.Description
+ }
+
+ BananaSplitBuff: {
+ DisplayName: Banana Split Buff
+ Description: Mods.Everglow.Buffs.BananaSplitBuff.Description
+ }
+
+ BBQRibsBuff: {
+ DisplayName: B B Q Ribs Buff
+ Description: Mods.Everglow.Buffs.BBQRibsBuff.Description
+ }
+
+ BlackCurrantBuff: {
+ DisplayName: Black Currant Buff
+ Description: Mods.Everglow.Buffs.BlackCurrantBuff.Description
+ }
+
+ BloodOrangeBuff: {
+ DisplayName: Blood Orange Buff
+ Description: Mods.Everglow.Buffs.BloodOrangeBuff.Description
+ }
+
+ BowlofSoupBuff: {
+ DisplayName: Bowlof Soup Buff
+ Description: Mods.Everglow.Buffs.BowlofSoupBuff.Description
+ }
+
+ BunnyStewBuff: {
+ DisplayName: Bunny Stew Buff
+ Description: Mods.Everglow.Buffs.BunnyStewBuff.Description
+ }
+
+ BurgerBuff: {
+ DisplayName: Burger Buff
+ Description: Mods.Everglow.Buffs.BurgerBuff.Description
+ }
+
+ CherryBuff: {
+ DisplayName: Cherry Buff
+ Description: Mods.Everglow.Buffs.CherryBuff.Description
+ }
+
+ ChickenNuggetBuff: {
+ DisplayName: Chicken Nugget Buff
+ Description: Mods.Everglow.Buffs.ChickenNuggetBuff.Description
+ }
+
+ ChocolateChipCookieBuff: {
+ DisplayName: Chocolate Chip Cookie Buff
+ Description: Mods.Everglow.Buffs.ChocolateChipCookieBuff.Description
+ }
+
+ ChristmasPuddingBuff: {
+ DisplayName: Christmas Pudding Buff
+ Description: Mods.Everglow.Buffs.ChristmasPuddingBuff.Description
+ }
+
+ CoconutBuff: {
+ DisplayName: Coconut Buff
+ Description: Mods.Everglow.Buffs.CoconutBuff.Description
+ }
+
+ CookedFishBuff: {
+ DisplayName: Cooked Fish Buff
+ Description: Mods.Everglow.Buffs.CookedFishBuff.Description
+ }
+
+ CookedMarshmallowBuff: {
+ DisplayName: Cooked Marshmallow Buff
+ Description: Mods.Everglow.Buffs.CookedMarshmallowBuff.Description
+ }
+
+ CookedShrimpBuff: {
+ DisplayName: Cooked Shrimp Buff
+ Description: Mods.Everglow.Buffs.CookedShrimpBuff.Description
+ }
+
+ DragonfruitBuff: {
+ DisplayName: Dragonfruit Buff
+ Description: Mods.Everglow.Buffs.DragonfruitBuff.Description
+ }
+
+ ElderberryBuff: {
+ DisplayName: Elderberry Buff
+ Description: Mods.Everglow.Buffs.ElderberryBuff.Description
+ }
+
+ EscargotBuff: {
+ DisplayName: Escargot Buff
+ Description: Mods.Everglow.Buffs.EscargotBuff.Description
+ }
+
+ FriedEggBuff: {
+ DisplayName: Fried Egg Buff
+ Description: Mods.Everglow.Buffs.FriedEggBuff.Description
+ }
+
+ FriesBuff: {
+ DisplayName: Fries Buff
+ Description: Mods.Everglow.Buffs.FriesBuff.Description
+ }
+
+ FroggleBunwichBuff: {
+ DisplayName: Froggle Bunwich Buff
+ Description: Mods.Everglow.Buffs.FroggleBunwichBuff.Description
+ }
+
+ FruitSaladBuff: {
+ DisplayName: Fruit Salad Buff
+ Description: Mods.Everglow.Buffs.FruitSaladBuff.Description
+ }
+
+ GingerbreadCookieBuff: {
+ DisplayName: Gingerbread Cookie Buff
+ Description: Mods.Everglow.Buffs.GingerbreadCookieBuff.Description
+ }
+
+ GoldenDelightBuff: {
+ DisplayName: Golden Delight Buff
+ Description: Mods.Everglow.Buffs.GoldenDelightBuff.Description
+ }
+
+ GrapefruitBuff: {
+ DisplayName: Grapefruit Buff
+ Description: Mods.Everglow.Buffs.GrapefruitBuff.Description
+ }
+
+ GrapesBuff: {
+ DisplayName: Grapes Buff
+ Description: Mods.Everglow.Buffs.GrapesBuff.Description
+ }
+
+ GrilledSquirrelBuff: {
+ DisplayName: Grilled Squirrel Buff
+ Description: Mods.Everglow.Buffs.GrilledSquirrelBuff.Description
+ }
+
+ GrubSoupBuff: {
+ DisplayName: Grub Soup Buff
+ Description: Mods.Everglow.Buffs.GrubSoupBuff.Description
+ }
+
+ HotdogBuff: {
+ DisplayName: Hotdog Buff
+ Description: Mods.Everglow.Buffs.HotdogBuff.Description
+ }
+
+ IceCreamBuff: {
+ DisplayName: Ice Cream Buff
+ Description: Mods.Everglow.Buffs.IceCreamBuff.Description
+ }
+
+ LemonBuff: {
+ DisplayName: Lemon Buff
+ Description: Mods.Everglow.Buffs.LemonBuff.Description
+ }
+
+ LobsterTailBuff: {
+ DisplayName: Lobster Tail Buff
+ Description: Mods.Everglow.Buffs.LobsterTailBuff.Description
+ }
+
+ MangoBuff: {
+ DisplayName: Mango Buff
+ Description: Mods.Everglow.Buffs.MangoBuff.Description
+ }
+
+ MarshmallowBuff: {
+ DisplayName: Marshmallow Buff
+ Description: Mods.Everglow.Buffs.MarshmallowBuff.Description
+ }
+
+ MonsterLasagnaBuff: {
+ DisplayName: Monster Lasagna Buff
+ Description: Mods.Everglow.Buffs.MonsterLasagnaBuff.Description
+ }
+
+ NachosBuff: {
+ DisplayName: Nachos Buff
+ Description: Mods.Everglow.Buffs.NachosBuff.Description
+ }
+
+ PadThaiBuff: {
+ DisplayName: Pad Thai Buff
+ Description: Mods.Everglow.Buffs.PadThaiBuff.Description
+ }
+
+ PeachBuff: {
+ DisplayName: Peach Buff
+ Description: Mods.Everglow.Buffs.PeachBuff.Description
+ }
+
+ PhoBuff: {
+ DisplayName: Pho Buff
+ Description: Mods.Everglow.Buffs.PhoBuff.Description
+ }
+
+ PineappleBuff: {
+ DisplayName: Pineapple Buff
+ Description: Mods.Everglow.Buffs.PineappleBuff.Description
+ }
+
+ PizzaBuff: {
+ DisplayName: Pizza Buff
+ Description: Mods.Everglow.Buffs.PizzaBuff.Description
+ }
+
+ PlumBuff: {
+ DisplayName: Plum Buff
+ Description: Mods.Everglow.Buffs.PlumBuff.Description
+ }
+
+ PotatoChipsBuff: {
+ DisplayName: Potato Chips Buff
+ Description: Mods.Everglow.Buffs.PotatoChipsBuff.Description
+ }
+
+ PumpkinPieBuff: {
+ DisplayName: Pumpkin Pie Buff
+ Description: Mods.Everglow.Buffs.PumpkinPieBuff.Description
+ }
+
+ RambutanBuff: {
+ DisplayName: Rambutan Buff
+ Description: Mods.Everglow.Buffs.RambutanBuff.Description
+ }
+
+ RoastedBirdBuff: {
+ DisplayName: Roasted Bird Buff
+ Description: Mods.Everglow.Buffs.RoastedBirdBuff.Description
+ }
+
+ RoastedDuckBuff: {
+ DisplayName: Roasted Duck Buff
+ Description: Mods.Everglow.Buffs.RoastedDuckBuff.Description
+ }
+
+ SashimiBuff: {
+ DisplayName: Sashimi Buff
+ Description: Mods.Everglow.Buffs.SashimiBuff.Description
+ }
+
+ SauteedFrogLegsBuff: {
+ DisplayName: Sauteed Frog Legs Buff
+ Description: Mods.Everglow.Buffs.SauteedFrogLegsBuff.Description
+ }
+
+ SeafoodDinnerBuff: {
+ DisplayName: Seafood Dinner Buff
+ Description: Mods.Everglow.Buffs.SeafoodDinnerBuff.Description
+ }
+
+ ShrimpPoBoyBuff: {
+ DisplayName: Shrimp Po Boy Buff
+ Description: Mods.Everglow.Buffs.ShrimpPoBoyBuff.Description
+ }
+
+ ShuckedOysterBuff: {
+ DisplayName: Shucked Oyster Buff
+ Description: Mods.Everglow.Buffs.ShuckedOysterBuff.Description
+ }
+
+ SpaghettiBuff: {
+ DisplayName: Spaghetti Buff
+ Description: Mods.Everglow.Buffs.SpaghettiBuff.Description
+ }
+
+ StarfruitBuff: {
+ DisplayName: Starfruit Buff
+ Description: Mods.Everglow.Buffs.StarfruitBuff.Description
+ }
+
+ SteakBuff: {
+ DisplayName: Steak Buff
+ Description: Mods.Everglow.Buffs.SteakBuff.Description
+ }
+
+ SugarCookieBuff: {
+ DisplayName: Sugar Cookie Buff
+ Description: Mods.Everglow.Buffs.SugarCookieBuff.Description
+ }
+
+ AleBuff: {
+ DisplayName: Ale Buff
+ Description: Mods.Everglow.Buffs.AleBuff.Description
+ }
+
+ AppleJuiceBuff: {
+ DisplayName: Apple Juice Buff
+ Description: Mods.Everglow.Buffs.AppleJuiceBuff.Description
+ }
+
+ BananaDaiquiriBuff: {
+ DisplayName: Banana Daiquiri Buff
+ Description: Mods.Everglow.Buffs.BananaDaiquiriBuff.Description
+ }
+
+ BloodyMoscatoBuff: {
+ DisplayName: Bloody Moscato Buff
+ Description: Mods.Everglow.Buffs.BloodyMoscatoBuff.Description
+ }
+
+ CoffeeCupBuff: {
+ DisplayName: Coffee Cup Buff
+ Description: Mods.Everglow.Buffs.CoffeeCupBuff.Description
+ }
+
+ CreamSodaBuff: {
+ DisplayName: Cream Soda Buff
+ Description: Mods.Everglow.Buffs.CreamSodaBuff.Description
+ }
+
+ FruitJuiceBuff: {
+ DisplayName: Fruit Juice Buff
+ Description: Mods.Everglow.Buffs.FruitJuiceBuff.Description
+ }
+
+ GrapeJuiceBuff: {
+ DisplayName: Grape Juice Buff
+ Description: Mods.Everglow.Buffs.GrapeJuiceBuff.Description
+ }
+
+ LemonadeBuff: {
+ DisplayName: Lemonade Buff
+ Description: Mods.Everglow.Buffs.LemonadeBuff.Description
+ }
+
+ MilkCartonBuff: {
+ DisplayName: Milk Carton Buff
+ Description: Mods.Everglow.Buffs.MilkCartonBuff.Description
+ }
+
+ MilkshakeBuff: {
+ DisplayName: Milkshake Buff
+ Description: Mods.Everglow.Buffs.MilkshakeBuff.Description
+ }
+
+ PeachSangriaBuff: {
+ DisplayName: Peach Sangria Buff
+ Description: Mods.Everglow.Buffs.PeachSangriaBuff.Description
+ }
+
+ PinaColadaBuff: {
+ DisplayName: Pina Colada Buff
+ Description: Mods.Everglow.Buffs.PinaColadaBuff.Description
+ }
+
+ PrismaticPunchBuff: {
+ DisplayName: Prismatic Punch Buff
+ Description: Mods.Everglow.Buffs.PrismaticPunchBuff.Description
+ }
+
+ SakeBuff: {
+ DisplayName: Sake Buff
+ Description: Mods.Everglow.Buffs.SakeBuff.Description
+ }
+
+ SmoothieofDarknessBuff: {
+ DisplayName: Smoothieof Darkness Buff
+ Description: Mods.Everglow.Buffs.SmoothieofDarknessBuff.Description
+ }
+
+ TeacupBuff: {
+ DisplayName: Teacup Buff
+ Description: Mods.Everglow.Buffs.TeacupBuff.Description
+ }
+
+ TropicalSmoothieBuff: {
+ DisplayName: Tropical Smoothie Buff
+ Description: Mods.Everglow.Buffs.TropicalSmoothieBuff.Description
+ }
+
+ ArcticshellfishWarshipBuff: {
+ DisplayName: Arcticshellfish Warship Buff
+ Description: Mods.Everglow.Buffs.ArcticshellfishWarshipBuff.Description
+ }
+
+ BakedMusselBuff: {
+ DisplayName: Baked Mussel Buff
+ Description: Mods.Everglow.Buffs.BakedMusselBuff.Description
+ }
+
+ BakedOysterBuff: {
+ DisplayName: Baked Oyster Buff
+ Description: Mods.Everglow.Buffs.BakedOysterBuff.Description
+ }
+
+ CantaloupeJellyBuff: {
+ DisplayName: Cantaloupe Jelly Buff
+ Description: Mods.Everglow.Buffs.CantaloupeJellyBuff.Description
+ }
+
+ CaramelPuddingBuff: {
+ DisplayName: Caramel Pudding Buff
+ Description: Mods.Everglow.Buffs.CaramelPuddingBuff.Description
+ }
+
+ CrabseedWarshipBuff: {
+ DisplayName: Crabseed Warship Buff
+ Description: Mods.Everglow.Buffs.CrabseedWarshipBuff.Description
+ }
+
+ DurianBuff: {
+ DisplayName: Durian Buff
+ Description: Mods.Everglow.Buffs.DurianBuff.Description
+ }
+
+ EggTartBuff: {
+ DisplayName: Egg Tart Buff
+ Description: Mods.Everglow.Buffs.EggTartBuff.Description
+ }
+
+ KiwiFruitBuff: {
+ DisplayName: Kiwi Fruit Buff
+ Description: Mods.Everglow.Buffs.KiwiFruitBuff.Description
+ }
+
+ KiwiIceCreamBuff: {
+ DisplayName: Kiwi Ice Cream Buff
+ Description: Mods.Everglow.Buffs.KiwiIceCreamBuff.Description
+ }
+
+ MangosteenBuff: {
+ DisplayName: Mangosteen Buff
+ Description: Mods.Everglow.Buffs.MangosteenBuff.Description
+ }
+
+ OrangeIcecreamBuff: {
+ DisplayName: Orange Icecream Buff
+ Description: Mods.Everglow.Buffs.OrangeIcecreamBuff.Description
+ }
+
+ SalmonInPepperBuff: {
+ DisplayName: Salmon In Pepper Buff
+ Description: Mods.Everglow.Buffs.SalmonInPepperBuff.Description
+ }
+
+ SalmonWarshipBuff: {
+ DisplayName: Salmon Warship Buff
+ Description: Mods.Everglow.Buffs.SalmonWarshipBuff.Description
+ }
+
+ SeafoodPizzaBuff: {
+ DisplayName: Seafood Pizza Buff
+ Description: Mods.Everglow.Buffs.SeafoodPizzaBuff.Description
+ }
+
+ StinkyTofuBuff: {
+ DisplayName: Stinky Tofu Buff
+ Description: Mods.Everglow.Buffs.StinkyTofuBuff.Description
+ }
+
+ StrawberryBuff: {
+ DisplayName: Strawberry Buff
+ Description: Mods.Everglow.Buffs.StrawberryBuff.Description
+ }
+
+ StrawberryIcecreamBuff: {
+ DisplayName: Strawberry Icecream Buff
+ Description: Mods.Everglow.Buffs.StrawberryIcecreamBuff.Description
+ }
+
+ SweetshrimpSushiBuff: {
+ DisplayName: Sweetshrimp Sushi Buff
+ Description: Mods.Everglow.Buffs.SweetshrimpSushiBuff.Description
+ }
+
+ TamakoSushiBuff: {
+ DisplayName: Tamako Sushi Buff
+ Description: Mods.Everglow.Buffs.TamakoSushiBuff.Description
+ }
+
+ WakameWarshipBuff: {
+ DisplayName: Wakame Warship Buff
+ Description: Mods.Everglow.Buffs.WakameWarshipBuff.Description
+ }
+
+ WatermelonBuff: {
+ DisplayName: Watermelon Buff
+ Description: Mods.Everglow.Buffs.WatermelonBuff.Description
+ }
+
+ WatermelonPlateBuff: {
+ DisplayName: Watermelon Plate Buff
+ Description: Mods.Everglow.Buffs.WatermelonPlateBuff.Description
+ }
+
+ BlueHawaiiBuff: {
+ DisplayName: Blue Hawaii Buff
+ Description: Mods.Everglow.Buffs.BlueHawaiiBuff.Description
+ }
+
+ B_52Buff: {
+ DisplayName: B_52 Buff
+ Description: Mods.Everglow.Buffs.B_52Buff.Description
+ }
+
+ DreamYearningBuff: {
+ DisplayName: Dream Yearning Buff
+ Description: Mods.Everglow.Buffs.DreamYearningBuff.Description
+ }
+
+ DryMartiniBuff: {
+ DisplayName: Dry Martini Buff
+ Description: Mods.Everglow.Buffs.DryMartiniBuff.Description
+ }
+
+ GreenStormBuff: {
+ DisplayName: Green Storm Buff
+ Description: Mods.Everglow.Buffs.GreenStormBuff.Description
+ }
+
+ KiwiJuiceBuff: {
+ DisplayName: Kiwi Juice Buff
+ Description: Mods.Everglow.Buffs.KiwiJuiceBuff.Description
+ }
+
+ LonelyJellyfishBuff: {
+ DisplayName: Lonely Jellyfish Buff
+ Description: Mods.Everglow.Buffs.LonelyJellyfishBuff.Description
+ }
+
+ OrangeJuiceBuff: {
+ DisplayName: Orange Juice Buff
+ Description: Mods.Everglow.Buffs.OrangeJuiceBuff.Description
+ }
+
+ PiercoldWindBuff: {
+ DisplayName: Piercold Wind Buff
+ Description: Mods.Everglow.Buffs.PiercoldWindBuff.Description
+ }
+
+ PurpleHooterBuff: {
+ DisplayName: Purple Hooter Buff
+ Description: Mods.Everglow.Buffs.PurpleHooterBuff.Description
+ }
+
+ QuinceMarryBuff: {
+ DisplayName: Quince Marry Buff
+ Description: Mods.Everglow.Buffs.QuinceMarryBuff.Description
+ }
+
+ RedWineBuff: {
+ DisplayName: Red Wine Buff
+ Description: Mods.Everglow.Buffs.RedWineBuff.Description
+ }
+
+ SunriseBuff: {
+ DisplayName: Sunrise Buff
+ Description: Mods.Everglow.Buffs.SunriseBuff.Description
+ }
+
+ TricolourBuff: {
+ DisplayName: Tricolour Buff
+ Description: Mods.Everglow.Buffs.TricolourBuff.Description
+ }
+
+ WaterMelonJuiceBuff: {
+ DisplayName: Water Melon Juice Buff
+ Description: Mods.Everglow.Buffs.WaterMelonJuiceBuff.Description
+ }
+
+ TuskStaff: {
+ DisplayName: Tusk Staff
+ Description: Mods.Everglow.Buffs.TuskStaff.Description
+ }
+
+ GlowMothBuff: {
+ DisplayName: Glow Moth Buff
+ Description: Mods.Everglow.Buffs.GlowMothBuff.Description
+ }
+
+ OnMoth: {
+ DisplayName: On Moth
+ Description: Mods.Everglow.Buffs.OnMoth.Description
+ }
+
+ Freeze: {
+ DisplayName: Freeze
+ Description: Mods.Everglow.Buffs.Freeze.Description
+ }
+
+ LaserWormBuff: {
+ DisplayName: Laser Worm Buff
+ Description: Mods.Everglow.Buffs.LaserWormBuff.Description
+ }
+
+ ShadowSupervisor: {
+ DisplayName: Shadow Supervisor
+ Description: Mods.Everglow.Buffs.ShadowSupervisor.Description
+ }
+
+ MoonAndFragrans: {
+ DisplayName: Moon And Fragrans
+ Description: Mods.Everglow.Buffs.MoonAndFragrans.Description
+ }
+
+ MoonAndFragransII: {
+ DisplayName: Moon And Fragrans I I
+ Description: Mods.Everglow.Buffs.MoonAndFragransII.Description
+ }
+
+ MoonAndFragransIII: {
+ DisplayName: Moon And Fragrans I I I
+ Description: Mods.Everglow.Buffs.MoonAndFragransIII.Description
+ }
+
+ WaterBoltII: {
+ DisplayName: Water Bolt I I
+ Description: Mods.Everglow.Buffs.WaterBoltII.Description
+ }
+
+ BlueImmune: {
+ DisplayName: Blue Immune
+ Description: Mods.Everglow.Buffs.BlueImmune.Description
+ }
+
+ BrownImmune: {
+ DisplayName: Brown Immune
+ Description: Mods.Everglow.Buffs.BrownImmune.Description
+ }
+
+ GreenImmune: {
+ DisplayName: Green Immune
+ Description: Mods.Everglow.Buffs.GreenImmune.Description
+ }
+
+ PinkImmune: {
+ DisplayName: Pink Immune
+ Description: Mods.Everglow.Buffs.PinkImmune.Description
+ }
+
+ PurpleImmune: {
+ DisplayName: Purple Immune
+ Description: Mods.Everglow.Buffs.PurpleImmune.Description
+ }
+
+ RedImmune: {
+ DisplayName: Red Immune
+ Description: Mods.Everglow.Buffs.RedImmune.Description
+ }
+
+ WhiteImmune: {
+ DisplayName: White Immune
+ Description: Mods.Everglow.Buffs.WhiteImmune.Description
+ }
+
+ YellowImmune: {
+ DisplayName: Yellow Immune
+ Description: Mods.Everglow.Buffs.YellowImmune.Description
+ }
+
+ CactusBallBuff: {
+ DisplayName: Cactus Ball Buff
+ Description: Mods.Everglow.Buffs.CactusBallBuff.Description
+ }
+
+ DeathFlame: {
+ DisplayName: Death Flame
+ Description: Mods.Everglow.Buffs.DeathFlame.Description
+ }
+}
+
+Items: {
+ BottleOfNutShellFlowers: {
+ DisplayName: Bottle Of Nut Shell Flowers
+ Tooltip: ""
+ }
+
+ PlumBlossomInABowl: {
+ DisplayName: Plum Blossom In A Bowl
+ Tooltip: ""
+ }
+
+ WhiteLotusBonsai: {
+ DisplayName: White Lotus Bonsai
+ Tooltip: ""
+ }
+
+ BloodGoldBayonet: {
+ DisplayName: Blood Gold Bayonet
+ Tooltip: ""
+ }
+
+ BlueRibbonBayonet: {
+ DisplayName: Blue Ribbon Bayonet
+ Tooltip: ""
+ }
+
+ CopperBayonet: {
+ DisplayName: Copper Bayonet
+ Tooltip: ""
+ }
+
+ DreamStar: {
+ DisplayName: Dream Star
+ Tooltip: ""
+ }
+
+ EnchantedBayonet: {
+ DisplayName: Enchanted Bayonet
+ Tooltip: ""
+ }
+
+ EternalNight: {
+ DisplayName: Eternal Night
+ Tooltip: ""
+ }
+
+ GoldenStabbingSword: {
+ DisplayName: Golden Stabbing Sword
+ Tooltip: ""
+ }
+
+ HolyBayonet: {
+ DisplayName: Holy Bayonet
+ Tooltip: ""
+ }
+
+ IronStabbingSword: {
+ DisplayName: Iron Stabbing Sword
+ Tooltip: ""
+ }
+
+ LeadStabbingSword: {
+ DisplayName: Lead Stabbing Sword
+ Tooltip: ""
+ }
+
+ PlatinumStabbingSword: {
+ DisplayName: Platinum Stabbing Sword
+ Tooltip: ""
+ }
+
+ PrisonFireBayonet: {
+ DisplayName: Prison Fire Bayonet
+ Tooltip: ""
+ }
+
+ RedRibbonBayonet: {
+ DisplayName: Red Ribbon Bayonet
+ Tooltip: ""
+ }
+
+ RottenGoldBayonet: {
+ DisplayName: Rotten Gold Bayonet
+ Tooltip: ""
+ }
+
+ SilverStabbingSword: {
+ DisplayName: Silver Stabbing Sword
+ Tooltip: ""
+ }
+
+ TinStabbingSword: {
+ DisplayName: Tin Stabbing Sword
+ Tooltip: ""
+ }
+
+ TungstenStabbingSword: {
+ DisplayName: Tungsten Stabbing Sword
+ Tooltip: ""
+ }
+
+ VegetationBayonet: {
+ DisplayName: Vegetation Bayonet
+ Tooltip: ""
+ }
+
+ YoenLeZed: {
+ DisplayName: Yoen Le Zed
+ Tooltip: ""
+ }
+
+ StarSeed: {
+ DisplayName: Star Seed
+ Tooltip: ""
+ }
+
+ FryingPanItem: {
+ DisplayName: Frying Pan Item
+ Tooltip: ""
+ }
+
+ BloodGlucoseMonitor: {
+ DisplayName: Blood Glucose Monitor
+ Tooltip: ""
+ }
+
+ OsmoticPressureMonitor: {
+ DisplayName: Osmotic Pressure Monitor
+ Tooltip: ""
+ }
+
+ ArcticshellfishWarship: {
+ DisplayName: Arcticshellfish Warship
+ Tooltip: ""
+ }
+
+ BakedMussel: {
+ DisplayName: Baked Mussel
+ Tooltip: ""
+ }
+
+ BakedOyster: {
+ DisplayName: Baked Oyster
+ Tooltip: ""
+ }
+
+ CantaloupeJelly: {
+ DisplayName: Cantaloupe Jelly
+ Tooltip: ""
+ }
+
+ CaramelPudding: {
+ DisplayName: Caramel Pudding
+ Tooltip: ""
+ }
+
+ CrabseedWarship: {
+ DisplayName: Crabseed Warship
+ Tooltip: ""
+ }
+
+ Durian: {
+ DisplayName: Durian
+ Tooltip: ""
+ }
+
+ EggTart: {
+ DisplayName: Egg Tart
+ Tooltip: ""
+ }
+
+ KiwiFruit: {
+ DisplayName: Kiwi Fruit
+ Tooltip: ""
+ }
+
+ KiwiIceCream: {
+ DisplayName: Kiwi Ice Cream
+ Tooltip: ""
+ }
+
+ Mangosteen: {
+ DisplayName: Mangosteen
+ Tooltip: ""
+ }
+
+ OrangeIcecream: {
+ DisplayName: Orange Icecream
+ Tooltip: ""
+ }
+
+ SalmonInPepper: {
+ DisplayName: Salmon In Pepper
+ Tooltip: ""
+ }
+
+ SalmonWarship: {
+ DisplayName: Salmon Warship
+ Tooltip: ""
+ }
+
+ SeafoodPizza: {
+ DisplayName: Seafood Pizza
+ Tooltip: ""
+ }
+
+ StinkyTofu: {
+ DisplayName: Stinky Tofu
+ Tooltip: ""
+ }
+
+ Strawberry: {
+ DisplayName: Strawberry
+ Tooltip: ""
+ }
+
+ StrawberryIcecream: {
+ DisplayName: Strawberry Icecream
+ Tooltip: ""
+ }
+
+ SweetshrimpSushi: {
+ DisplayName: Sweetshrimp Sushi
+ Tooltip: ""
+ }
+
+ TamakoSushi: {
+ DisplayName: Tamako Sushi
+ Tooltip: ""
+ }
+
+ WakameWarship: {
+ DisplayName: Wakame Warship
+ Tooltip: ""
+ }
+
+ Watermelon: {
+ DisplayName: Watermelon
+ Tooltip: ""
+ }
+
+ WatermelonPlate: {
+ DisplayName: Watermelon Plate
+ Tooltip: ""
+ }
+
+ BlueHawaii: {
+ DisplayName: Blue Hawaii
+ Tooltip: ""
+ }
+
+ B_52: {
+ DisplayName: B_52
+ Tooltip: ""
+ }
+
+ DreamYearning: {
+ DisplayName: Dream Yearning
+ Tooltip: ""
+ }
+
+ DryMartini: {
+ DisplayName: Dry Martini
+ Tooltip: ""
+ }
+
+ GreenStorm: {
+ DisplayName: Green Storm
+ Tooltip: ""
+ }
+
+ KiwiJuice: {
+ DisplayName: Kiwi Juice
+ Tooltip: ""
+ }
+
+ LonelyJellyfish: {
+ DisplayName: Lonely Jellyfish
+ Tooltip: ""
+ }
+
+ OrangeJuice: {
+ DisplayName: Orange Juice
+ Tooltip: ""
+ }
+
+ PiercoldWind: {
+ DisplayName: Piercold Wind
+ Tooltip: ""
+ }
+
+ PurpleHooter: {
+ DisplayName: Purple Hooter
+ Tooltip: ""
+ }
+
+ QuinceMarry: {
+ DisplayName: Quince Marry
+ Tooltip: ""
+ }
+
+ RedWine: {
+ DisplayName: Red Wine
+ Tooltip: ""
+ }
+
+ Sunrise: {
+ DisplayName: Sunrise
+ Tooltip: ""
+ }
+
+ Tricolour: {
+ DisplayName: Tricolour
+ Tooltip: ""
+ }
+
+ WaterMelonJuice: {
+ DisplayName: Water Melon Juice
+ Tooltip: ""
+ }
+
+ VFXGenerator: {
+ DisplayName: V F X Generator
+ Tooltip: ""
+ }
+
+ AirTileItem: {
+ DisplayName: Air Tile Item
+ Tooltip: ""
+ }
+
+ AirWallItem: {
+ DisplayName: Air Wall Item
+ Tooltip: ""
+ }
+
+ VortexVanquisherItem: {
+ DisplayName: Vortex Vanquisher Item
+ Tooltip: ""
+ }
+
+ Tester: {
+ DisplayName: Tester
+ Tooltip: ""
+ }
+
+ BloodMossStone: {
+ DisplayName: Blood Moss Stone
+ Tooltip: ""
+ }
+
+ BloodyStoneWall: {
+ DisplayName: Bloody Stone Wall
+ Tooltip: ""
+ }
+
+ StoneTusk: {
+ DisplayName: Stone Tusk
+ Tooltip: ""
+ }
+
+ TuskFlesh: {
+ DisplayName: Tusk Flesh
+ Tooltip: ""
+ }
+
+ TuskStatusI: {
+ DisplayName: Tusk Status I
+ Tooltip: ""
+ }
+
+ TuskStatusII: {
+ DisplayName: Tusk Status I I
+ Tooltip: ""
+ }
+
+ TuskStatusIII: {
+ DisplayName: Tusk Status I I I
+ Tooltip: ""
+ }
+
+ TuskStatusIV: {
+ DisplayName: Tusk Status I V
+ Tooltip: ""
+ }
+
+ BloodyBoneYoyo: {
+ DisplayName: Bloody Bone Yoyo
+ Tooltip: ""
+ }
+
+ SpineGun: {
+ DisplayName: Spine Gun
+ Tooltip: ""
+ }
+
+ ToothBow: {
+ DisplayName: Tooth Bow
+ Tooltip: ""
+ }
+
+ ToothKnife: {
+ DisplayName: Tooth Knife
+ Tooltip: ""
+ }
+
+ ToothMagicBall: {
+ DisplayName: Tooth Magic Ball
+ Tooltip: ""
+ }
+
+ ToothSpear: {
+ DisplayName: Tooth Spear
+ Tooltip: ""
+ }
+
+ ToothStaff: {
+ DisplayName: Tooth Staff
+ Tooltip: ""
+ }
+
+ BloodyTuskTrophy: {
+ DisplayName: Bloody Tusk Trophy
+ Tooltip: ""
+ }
+
+ TuskRelic: {
+ DisplayName: Tusk Relic
+ Tooltip: ""
+ }
+
+ TuskTreasureBag: {
+ DisplayName: Tusk Treasure Bag
+ Tooltip: ""
+ }
+
+ TuskLace: {
+ DisplayName: Tusk Lace
+ Tooltip: ""
+ }
+
+ FireflyPylonItem: {
+ DisplayName: Firefly Pylon Item
+ Tooltip: ""
+ }
+
+ ShabbyPylonItem: {
+ DisplayName: Shabby Pylon Item
+ Tooltip: ""
+ }
+
+ BlackStarShrub: {
+ DisplayName: Black Star Shrub
+ Tooltip: ""
+ }
+
+ DarkCocoon: {
+ DisplayName: Dark Cocoon
+ Tooltip: ""
+ }
+
+ DarkCocoonWall: {
+ DisplayName: Dark Cocoon Wall
+ Tooltip: ""
+ }
+
+ EvilCocoon: {
+ DisplayName: Evil Cocoon
+ Tooltip: ""
+ }
+
+ FireflyCapital: {
+ DisplayName: Firefly Capital
+ Tooltip: ""
+ }
+
+ FireflyMoss: {
+ DisplayName: Firefly Moss
+ Tooltip: ""
+ }
+
+ FireflyPigment: {
+ DisplayName: Firefly Pigment
+ Tooltip: ""
+ }
+
+ GlowCrystal: {
+ DisplayName: Glow Crystal
+ Tooltip: ""
+ }
+
+ GlowingFirefly: {
+ DisplayName: Glowing Firefly
+ Tooltip: ""
+ }
+
+ GlowingPedal: {
+ DisplayName: Glowing Pedal
+ Tooltip: ""
+ }
+
+ GlowMetal: {
+ DisplayName: Glow Metal
+ Tooltip: ""
+ }
+
+ GlowStone: {
+ DisplayName: Glow Stone
+ Tooltip: ""
+ }
+
+ GlowWood: {
+ DisplayName: Glow Wood
+ Tooltip: ""
+ }
+
+ LiveFluorescentLeafWall: {
+ DisplayName: Live Fluorescent Leaf Wall
+ Tooltip: ""
+ }
+
+ LiveFluorescentWoodWall: {
+ DisplayName: Live Fluorescent Wood Wall
+ Tooltip: ""
+ }
+
+ MothScaleDust: {
+ DisplayName: Moth Scale Dust
+ Tooltip: ""
+ }
+
+ DarknessFan: {
+ DisplayName: Darkness Fan
+ Tooltip: ""
+ }
+
+ DreamWeaver: {
+ DisplayName: Dream Weaver
+ Tooltip: ""
+ }
+
+ DustOfCorrupt: {
+ DisplayName: Dust Of Corrupt
+ Tooltip: ""
+ }
+
+ EvilChrysalis: {
+ DisplayName: Evil Chrysalis
+ Tooltip: ""
+ }
+
+ FlowLightMissile: {
+ DisplayName: Flow Light Missile
+ Tooltip: ""
+ }
+
+ GlowBeadGun: {
+ DisplayName: Glow Bead Gun
+ Tooltip: ""
+ }
+
+ GlowWoodSword: {
+ DisplayName: Glow Wood Sword
+ Tooltip: ""
+ }
+
+ MothYoyo: {
+ DisplayName: Moth Yoyo
+ Tooltip: ""
+ }
+
+ NavyThunder: {
+ DisplayName: Navy Thunder
+ Tooltip: ""
+ }
+
+ PhosphorescenceGun: {
+ DisplayName: Phosphorescence Gun
+ Tooltip: ""
+ }
+
+ ScaleWingBlade: {
+ DisplayName: Scale Wing Blade
+ Tooltip: ""
+ }
+
+ ShadowWingBow: {
+ DisplayName: Shadow Wing Bow
+ Tooltip: ""
+ }
+
+ FluorescentLeafStaff: {
+ DisplayName: Fluorescent Leaf Staff
+ Tooltip: ""
+ }
+
+ FluorescentWoodStaff: {
+ DisplayName: Fluorescent Wood Staff
+ Tooltip: ""
+ }
+
+ GlowingDrop: {
+ DisplayName: Glowing Drop
+ Tooltip: ""
+ }
+
+ GlowWoodBed: {
+ DisplayName: Glow Wood Bed
+ Tooltip: ""
+ }
+
+ GlowWoodBookcase: {
+ DisplayName: Glow Wood Bookcase
+ Tooltip: ""
+ }
+
+ GlowWoodBookcaseType2: {
+ DisplayName: Glow Wood Bookcase Type2
+ Tooltip: ""
+ }
+
+ GlowWoodCampfire: {
+ DisplayName: Glow Wood Campfire
+ Tooltip: ""
+ }
+
+ GlowWoodCandelabra: {
+ DisplayName: Glow Wood Candelabra
+ Tooltip: ""
+ }
+
+ GlowWoodCandle: {
+ DisplayName: Glow Wood Candle
+ Tooltip: ""
+ }
+
+ GlowWoodChair: {
+ DisplayName: Glow Wood Chair
+ Tooltip: ""
+ }
+
+ GlowWoodChandelier: {
+ DisplayName: Glow Wood Chandelier
+ Tooltip: ""
+ }
+
+ GlowWoodChandelierType2: {
+ DisplayName: Glow Wood Chandelier Type2
+ Tooltip: ""
+ }
+
+ GlowWoodChandelierType3: {
+ DisplayName: Glow Wood Chandelier Type3
+ Tooltip: ""
+ }
+
+ GlowWoodChandelierType4: {
+ DisplayName: Glow Wood Chandelier Type4
+ Tooltip: ""
+ }
+
+ GlowWoodChest: {
+ DisplayName: Glow Wood Chest
+ Tooltip: ""
+ }
+
+ GlowWoodClock: {
+ DisplayName: Glow Wood Clock
+ Tooltip: ""
+ }
+
+ GlowWoodDoor: {
+ DisplayName: Glow Wood Door
+ Tooltip: ""
+ }
+
+ GlowWoodDoorType2: {
+ DisplayName: Glow Wood Door Type2
+ Tooltip: ""
+ }
+
+ GlowWoodDresser: {
+ DisplayName: Glow Wood Dresser
+ Tooltip: ""
+ }
+
+ GlowWoodDresserType2: {
+ DisplayName: Glow Wood Dresser Type2
+ Tooltip: ""
+ }
+
+ GlowWoodLamp: {
+ DisplayName: Glow Wood Lamp
+ Tooltip: ""
+ }
+
+ GlowWoodLantern: {
+ DisplayName: Glow Wood Lantern
+ Tooltip: ""
+ }
+
+ GlowWoodLanternType2: {
+ DisplayName: Glow Wood Lantern Type2
+ Tooltip: ""
+ }
+
+ GlowWoodMusicBox: {
+ DisplayName: Glow Wood Music Box
+ Tooltip: ""
+ }
+
+ GlowWoodPiano: {
+ DisplayName: Glow Wood Piano
+ Tooltip: ""
+ }
+
+ GlowWoodPlatform: {
+ DisplayName: Glow Wood Platform
+ Tooltip: ""
+ }
+
+ GlowWoodSink: {
+ DisplayName: Glow Wood Sink
+ Tooltip: ""
+ }
+
+ GlowWoodSinkType2: {
+ DisplayName: Glow Wood Sink Type2
+ Tooltip: ""
+ }
+
+ GlowWoodSofa: {
+ DisplayName: Glow Wood Sofa
+ Tooltip: ""
+ }
+
+ GlowWoodSofaType2: {
+ DisplayName: Glow Wood Sofa Type2
+ Tooltip: ""
+ }
+
+ GlowWoodTable: {
+ DisplayName: Glow Wood Table
+ Tooltip: ""
+ }
+
+ GlowWoodTorch: {
+ DisplayName: Glow Wood Torch
+ Tooltip: ""
+ }
+
+ GlowWoodWorkBench: {
+ DisplayName: Glow Wood Work Bench
+ Tooltip: ""
+ }
+
+ CorruptMothTreasureBag: {
+ DisplayName: Corrupt Moth Treasure Bag
+ Tooltip: ""
+ }
+
+ MothRelic: {
+ DisplayName: Moth Relic
+ Tooltip: ""
+ }
+
+ FireflyBorageBadge: {
+ DisplayName: Firefly Borage Badge
+ Tooltip: ""
+ }
+
+ MothEye: {
+ DisplayName: Moth Eye
+ Tooltip: ""
+ }
+
+ LilyHarp: {
+ DisplayName: Lily Harp
+ Tooltip: ""
+ }
+
+ BlueflowerBra: {
+ DisplayName: Blueflower Bra
+ Tooltip: ""
+ }
+
+ BlueflowerCap: {
+ DisplayName: Blueflower Cap
+ Tooltip: ""
+ }
+
+ BlueflowerDress: {
+ DisplayName: Blueflower Dress
+ Tooltip: ""
+ }
+
+ AshBone: {
+ DisplayName: Ash Bone
+ Tooltip: ""
+ }
+
+ BoneFeatherMagic: {
+ DisplayName: Bone Feather Magic
+ Tooltip: ""
+ }
+
+ CloudGun: {
+ DisplayName: Cloud Gun
+ Tooltip: ""
+ }
+
+ ComingGhost: {
+ DisplayName: Coming Ghost
+ Tooltip: ""
+ }
+
+ CyanFrost: {
+ DisplayName: Cyan Frost
+ Tooltip: ""
+ }
+
+ FeatherMagic: {
+ DisplayName: Feather Magic
+ Tooltip: ""
+ }
+
+ FireFeatherMagic: {
+ DisplayName: Fire Feather Magic
+ Tooltip: ""
+ }
+
+ FreezeFeatherMagic: {
+ DisplayName: Freeze Feather Magic
+ Tooltip: ""
+ }
+
+ GoldRoundYoyo: {
+ DisplayName: Gold Round Yoyo
+ Tooltip: ""
+ }
+
+ GoldRound: {
+ DisplayName: Gold Round
+ Tooltip: ""
+ }
+
+ Hepuyuan: {
+ DisplayName: Hepuyuan
+ Tooltip: ""
+ }
+
+ SilveralGun: {
+ DisplayName: Silveral Gun
+ Tooltip: ""
+ }
+
+ SilveralRifle: {
+ DisplayName: Silveral Rifle
+ Tooltip: ""
+ }
+
+ Sunflower: {
+ DisplayName: Sunflower
+ Tooltip: ""
+ }
+
+ ThunderFlower: {
+ DisplayName: Thunder Flower
+ Tooltip: ""
+ }
+
+ World: {
+ DisplayName: World
+ Tooltip: ""
+ }
+
+ XmasWhip: {
+ DisplayName: Xmas Whip
+ Tooltip: ""
+ }
+
+ AmbiguousNight: {
+ DisplayName: Ambiguous Night
+ Tooltip: ""
+ }
+
+ AmethystSlingshot: {
+ DisplayName: Amethyst Slingshot
+ Tooltip: ""
+ }
+
+ BorealWoodSlingshot: {
+ DisplayName: Boreal Wood Slingshot
+ Tooltip: ""
+ }
+
+ CactusSlingShot: {
+ DisplayName: Cactus Sling Shot
+ Tooltip: ""
+ }
+
+ DiamondSlingshot: {
+ DisplayName: Diamond Slingshot
+ Tooltip: ""
+ }
+
+ EbonwoodSlingshot: {
+ DisplayName: Ebonwood Slingshot
+ Tooltip: ""
+ }
+
+ EmeraldSlingshot: {
+ DisplayName: Emerald Slingshot
+ Tooltip: ""
+ }
+
+ GelSlingshot: {
+ DisplayName: Gel Slingshot
+ Tooltip: ""
+ }
+
+ JungleSlingshot: {
+ DisplayName: Jungle Slingshot
+ Tooltip: ""
+ }
+
+ PalmWoodSlingshot: {
+ DisplayName: Palm Wood Slingshot
+ Tooltip: ""
+ }
+
+ PearlwoodSlingshot: {
+ DisplayName: Pearlwood Slingshot
+ Tooltip: ""
+ }
+
+ RichMahoganySlingshot: {
+ DisplayName: Rich Mahogany Slingshot
+ Tooltip: ""
+ }
+
+ RubySlingshot: {
+ DisplayName: Ruby Slingshot
+ Tooltip: ""
+ }
+
+ SapphireSlingshot: {
+ DisplayName: Sapphire Slingshot
+ Tooltip: ""
+ }
+
+ ShadewoodSlingShot: {
+ DisplayName: Shadewood Sling Shot
+ Tooltip: ""
+ }
+
+ StarSlingshot: {
+ DisplayName: Star Slingshot
+ Tooltip: ""
+ }
+
+ TopazSlingshot: {
+ DisplayName: Topaz Slingshot
+ Tooltip: ""
+ }
+
+ WoodSlingshot: {
+ DisplayName: Wood Slingshot
+ Tooltip: ""
+ }
+
+ AdamantiteClub: {
+ DisplayName: Adamantite Club
+ Tooltip: ""
+ }
+
+ BorealWoodClub: {
+ DisplayName: Boreal Wood Club
+ Tooltip: ""
+ }
+
+ CactusClub: {
+ DisplayName: Cactus Club
+ Tooltip: ""
+ }
+
+ ChlorophyteClub: {
+ DisplayName: Chlorophyte Club
+ Tooltip: ""
+ }
+
+ CobaltClub: {
+ DisplayName: Cobalt Club
+ Tooltip: ""
+ }
+
+ CopperClub: {
+ DisplayName: Copper Club
+ Tooltip: ""
+ }
+
+ CorruptClub: {
+ DisplayName: Corrupt Club
+ Tooltip: ""
+ }
+
+ CrimsonClub: {
+ DisplayName: Crimson Club
+ Tooltip: ""
+ }
+
+ CrystalClub: {
+ DisplayName: Crystal Club
+ Tooltip: ""
+ }
+
+ CurseClub: {
+ DisplayName: Curse Club
+ Tooltip: ""
+ }
+
+ EbonwoodClub: {
+ DisplayName: Ebonwood Club
+ Tooltip: ""
+ }
+
+ GoldClub: {
+ DisplayName: Gold Club
+ Tooltip: ""
+ }
+
+ IchorClub: {
+ DisplayName: Ichor Club
+ Tooltip: ""
+ }
+
+ IronClub: {
+ DisplayName: Iron Club
+ Tooltip: ""
+ }
+
+ LeadClub: {
+ DisplayName: Lead Club
+ Tooltip: ""
+ }
+
+ MeteorClub: {
+ DisplayName: Meteor Club
+ Tooltip: ""
+ }
+
+ MithrilClub: {
+ DisplayName: Mithril Club
+ Tooltip: ""
+ }
+
+ OrichalcumClub: {
+ DisplayName: Orichalcum Club
+ Tooltip: ""
+ }
+
+ PalladiumClub: {
+ DisplayName: Palladium Club
+ Tooltip: ""
+ }
+
+ PalmWoodClub: {
+ DisplayName: Palm Wood Club
+ Tooltip: ""
+ }
+
+ PearlwoodClub: {
+ DisplayName: Pearlwood Club
+ Tooltip: ""
+ }
+
+ PlatinumClub: {
+ DisplayName: Platinum Club
+ Tooltip: ""
+ }
+
+ RichMahoganyClub: {
+ DisplayName: Rich Mahogany Club
+ Tooltip: ""
+ }
+
+ ShadewoodClub: {
+ DisplayName: Shadewood Club
+ Tooltip: ""
+ }
+
+ SilverClub: {
+ DisplayName: Silver Club
+ Tooltip: ""
+ }
+
+ SpikeClub: {
+ DisplayName: Spike Club
+ Tooltip: ""
+ }
+
+ StarDancer: {
+ DisplayName: Star Dancer
+ Tooltip: ""
+ }
+
+ TinClub: {
+ DisplayName: Tin Club
+ Tooltip: ""
+ }
+
+ TitaniumClub: {
+ DisplayName: Titanium Club
+ Tooltip: ""
+ }
+
+ TungstenClub: {
+ DisplayName: Tungsten Club
+ Tooltip: ""
+ }
+
+ WoodenClub: {
+ DisplayName: Wooden Club
+ Tooltip: ""
+ }
+
+ CloudBall: {
+ DisplayName: Cloud Ball
+ Tooltip: ""
+ }
+
+ BlueGel: {
+ DisplayName: Blue Gel
+ Tooltip: ""
+ }
+
+ CorruptEye: {
+ DisplayName: Corrupt Eye
+ Tooltip: ""
+ }
+
+ DukeTooth: {
+ DisplayName: Duke Tooth
+ Tooltip: ""
+ }
+
+ GoldLiquidPupil: {
+ DisplayName: Gold Liquid Pupil
+ Tooltip: ""
+ }
+
+ GreenGel: {
+ DisplayName: Green Gel
+ Tooltip: ""
+ }
+
+ JungleVitamin: {
+ DisplayName: Jungle Vitamin
+ Tooltip: ""
+ }
+
+ Odd8Ring: {
+ DisplayName: Odd8 Ring
+ Tooltip: ""
+ }
+
+ RedGel: {
+ DisplayName: Red Gel
+ Tooltip: ""
+ }
+
+ SilverWing: {
+ DisplayName: Silver Wing
+ Tooltip: ""
+ }
+
+ WalnutClip: {
+ DisplayName: Walnut Clip
+ Tooltip: ""
+ }
+
+ FixCoinCrit1: {
+ DisplayName: Fix Coin Crit1
+ Tooltip: ""
+ }
+
+ FixCoinCrit2: {
+ DisplayName: Fix Coin Crit2
+ Tooltip: ""
+ }
+
+ FixCoinCrit3: {
+ DisplayName: Fix Coin Crit3
+ Tooltip: ""
+ }
+
+ FixCoinCrit4: {
+ DisplayName: Fix Coin Crit4
+ Tooltip: ""
+ }
+
+ FixCoinCrit5: {
+ DisplayName: Fix Coin Crit5
+ Tooltip: ""
+ }
+
+ FixCoinDamage1: {
+ DisplayName: Fix Coin Damage1
+ Tooltip: ""
+ }
+
+ FixCoinDamage2: {
+ DisplayName: Fix Coin Damage2
+ Tooltip: ""
+ }
+
+ FixCoinDamage3: {
+ DisplayName: Fix Coin Damage3
+ Tooltip: ""
+ }
+
+ FixCoinDamage4: {
+ DisplayName: Fix Coin Damage4
+ Tooltip: ""
+ }
+
+ FixCoinDamage5: {
+ DisplayName: Fix Coin Damage5
+ Tooltip: ""
+ }
+
+ FixCoinDefense1: {
+ DisplayName: Fix Coin Defense1
+ Tooltip: ""
+ }
+
+ FixCoinDefense2: {
+ DisplayName: Fix Coin Defense2
+ Tooltip: ""
+ }
+
+ FixCoinDefense3: {
+ DisplayName: Fix Coin Defense3
+ Tooltip: ""
+ }
+
+ FixCoinDefense4: {
+ DisplayName: Fix Coin Defense4
+ Tooltip: ""
+ }
+
+ FixCoinDefense5: {
+ DisplayName: Fix Coin Defense5
+ Tooltip: ""
+ }
+
+ FixCoinMelee1: {
+ DisplayName: Fix Coin Melee1
+ Tooltip: ""
+ }
+
+ FixCoinMelee2: {
+ DisplayName: Fix Coin Melee2
+ Tooltip: ""
+ }
+
+ FixCoinMelee3: {
+ DisplayName: Fix Coin Melee3
+ Tooltip: ""
+ }
+
+ FixCoinSpeed1: {
+ DisplayName: Fix Coin Speed1
+ Tooltip: ""
+ }
+
+ FixCoinSpeed2: {
+ DisplayName: Fix Coin Speed2
+ Tooltip: ""
+ }
+
+ FixCoinSpeed3: {
+ DisplayName: Fix Coin Speed3
+ Tooltip: ""
+ }
+
+ CrystalSkull: {
+ DisplayName: Crystal Skull
+ Tooltip: ""
+ }
+
+ BloodLamp: {
+ DisplayName: Blood Lamp
+ Tooltip: ""
+ }
+
+ LanternBombRemoteControl: {
+ DisplayName: Lantern Bomb Remote Control
+ Tooltip: ""
+ }
+
+ CactusBall: {
+ DisplayName: Cactus Ball
+ Tooltip: ""
+ }
+
+ BlueFreeze: {
+ DisplayName: Blue Freeze
+ Tooltip: ""
+ }
+
+ BluePedal: {
+ DisplayName: Blue Pedal
+ Tooltip: ""
+ }
+
+ CyanHyacinth: {
+ DisplayName: Cyan Hyacinth
+ Tooltip: ""
+ }
+
+ DarkPoppy: {
+ DisplayName: Dark Poppy
+ Tooltip: ""
+ }
+
+ FlowerBrochure: {
+ DisplayName: Flower Brochure
+ Tooltip: ""
+ }
+
+ GoldCup: {
+ DisplayName: Gold Cup
+ Tooltip: ""
+ }
+
+ GoldWhip: {
+ DisplayName: Gold Whip
+ Tooltip: ""
+ }
+
+ HotPinkTulip: {
+ DisplayName: Hot Pink Tulip
+ Tooltip: ""
+ }
+
+ Lavender: {
+ DisplayName: Lavender
+ Tooltip: ""
+ }
+
+ LightChrysanthemum: {
+ DisplayName: Light Chrysanthemum
+ Tooltip: ""
+ }
+
+ LightPurpleBalls: {
+ DisplayName: Light Purple Balls
+ Tooltip: ""
+ }
+
+ OrangeSausage: {
+ DisplayName: Orange Sausage
+ Tooltip: ""
+ }
+
+ OrangeTulip: {
+ DisplayName: Orange Tulip
+ Tooltip: ""
+ }
+
+ PinkSun: {
+ DisplayName: Pink Sun
+ Tooltip: ""
+ }
+
+ PurplePhantom: {
+ DisplayName: Purple Phantom
+ Tooltip: ""
+ }
+
+ PurpleTail: {
+ DisplayName: Purple Tail
+ Tooltip: ""
+ }
+
+ RedFlame: {
+ DisplayName: Red Flame
+ Tooltip: ""
+ }
+
+ ShallowNight: {
+ DisplayName: Shallow Night
+ Tooltip: ""
+ }
+
+ SilverClock: {
+ DisplayName: Silver Clock
+ Tooltip: ""
+ }
+
+ WhiteStar: {
+ DisplayName: White Star
+ Tooltip: ""
+ }
+
+ WhiteTulip: {
+ DisplayName: White Tulip
+ Tooltip: ""
+ }
+
+ WindMoveSeed: {
+ DisplayName: Wind Move Seed
+ Tooltip: ""
+ }
+
+ BlueTorchFlower: {
+ DisplayName: Blue Torch Flower
+ Tooltip: ""
+ }
+
+ CyanBranch: {
+ DisplayName: Cyan Branch
+ Tooltip: ""
+ }
+
+ CyanPedal: {
+ DisplayName: Cyan Pedal
+ Tooltip: ""
+ }
+
+ DarkHat: {
+ DisplayName: Dark Hat
+ Tooltip: ""
+ }
+
+ HotPinkCrown: {
+ DisplayName: Hot Pink Crown
+ Tooltip: ""
+ }
+
+ LightPurplePen: {
+ DisplayName: Light Purple Pen
+ Tooltip: ""
+ }
+
+ ManyWhiteFlower: {
+ DisplayName: Many White Flower
+ Tooltip: ""
+ }
+
+ OrangeCrown: {
+ DisplayName: Orange Crown
+ Tooltip: ""
+ }
+
+ OrangeStick: {
+ DisplayName: Orange Stick
+ Tooltip: ""
+ }
+
+ PinkFourPedal: {
+ DisplayName: Pink Four Pedal
+ Tooltip: ""
+ }
+
+ PurpleBall: {
+ DisplayName: Purple Ball
+ Tooltip: ""
+ }
+
+ PurpleReedHalo: {
+ DisplayName: Purple Reed Halo
+ Tooltip: ""
+ }
+
+ RedTriangle: {
+ DisplayName: Red Triangle
+ Tooltip: ""
+ }
+
+ SilverCupFlower: {
+ DisplayName: Silver Cup Flower
+ Tooltip: ""
+ }
+
+ ThreeColorCrown: {
+ DisplayName: Three Color Crown
+ Tooltip: ""
+ }
+
+ WhiteCrown: {
+ DisplayName: White Crown
+ Tooltip: ""
+ }
+
+ WhitePedal: {
+ DisplayName: White Pedal
+ Tooltip: ""
+ }
+
+ WhiteWoodFlower: {
+ DisplayName: White Wood Flower
+ Tooltip: ""
+ }
+
+ YellowBellFlower: {
+ DisplayName: Yellow Bell Flower
+ Tooltip: ""
+ }
+
+ TreePlacer: {
+ DisplayName: Tree Placer
+ Tooltip: ""
+ }
+
+ TwilightWood: {
+ DisplayName: Twilight Wood
+ Tooltip: ""
+ }
+
+ YggdrasilImpression: {
+ DisplayName: Yggdrasil Impression
+ Tooltip: ""
+ }
+
+ ChinesePartitionLamp: {
+ DisplayName: Chinese Partition Lamp
+ Tooltip: ""
+ }
+
+ ChineseStyleFloorLamp: {
+ DisplayName: Chinese Style Floor Lamp
+ Tooltip: ""
+ }
+
+ CyanVineBar: {
+ DisplayName: Cyan Vine Bar
+ Tooltip: ""
+ }
+
+ CyanVineOre: {
+ DisplayName: Cyan Vine Ore
+ Tooltip: ""
+ }
+
+ DoubleArmsChineseStreetLamp: {
+ DisplayName: Double Arms Chinese Street Lamp
+ Tooltip: ""
+ }
+
+ HangingSkyLantern: {
+ DisplayName: Hanging Sky Lantern
+ Tooltip: ""
+ }
+
+ HexagonalCeilingLamp: {
+ DisplayName: Hexagonal Ceiling Lamp
+ Tooltip: ""
+ }
+
+ ShoreMud: {
+ DisplayName: Shore Mud
+ Tooltip: ""
+ }
+
+ SideHangingLantern: {
+ DisplayName: Side Hanging Lantern
+ Tooltip: ""
+ }
+
+ SideHangingLantern_White: {
+ DisplayName: Side Hanging Lantern_ White
+ Tooltip: ""
+ }
+
+ StoneDragonScaleWood: {
+ DisplayName: Stone Dragon Scale Wood
+ Tooltip: ""
+ }
+
+ StoneDragonScaleWoodWall: {
+ DisplayName: Stone Dragon Scale Wood Wall
+ Tooltip: ""
+ }
+
+ StreetLantern: {
+ DisplayName: Street Lantern
+ Tooltip: ""
+ }
+
+ YellowDynastyShingles: {
+ DisplayName: Yellow Dynasty Shingles
+ Tooltip: ""
+ }
+
+ YggdrasilAmber: {
+ DisplayName: Yggdrasil Amber
+ Tooltip: ""
+ }
+
+ CyanVineAxe: {
+ DisplayName: Cyan Vine Axe
+ Tooltip: ""
+ }
+
+ CyanVineHammer: {
+ DisplayName: Cyan Vine Hammer
+ Tooltip: ""
+ }
+
+ CyanVinePickaxe: {
+ DisplayName: Cyan Vine Pickaxe
+ Tooltip: ""
+ }
+
+ CyanVineSword: {
+ DisplayName: Cyan Vine Sword
+ Tooltip: ""
+ }
+
+ CyanVineThrowingSpear: {
+ DisplayName: Cyan Vine Throwing Spear
+ Tooltip: ""
+ }
+
+ DragonScaleWood: {
+ DisplayName: Dragon Scale Wood
+ Tooltip: ""
+ }
+
+ DragonScaleWoodWall: {
+ DisplayName: Dragon Scale Wood Wall
+ Tooltip: ""
+ }
+
+ OldMoss: {
+ DisplayName: Old Moss
+ Tooltip: ""
+ }
+
+ YggdrasilDirt: {
+ DisplayName: Yggdrasil Dirt
+ Tooltip: ""
+ }
+
+ AcroporaSpear: {
+ DisplayName: Acropora Spear
+ Tooltip: ""
+ }
+
+ CyanWindGranite: {
+ DisplayName: Cyan Wind Granite
+ Tooltip: ""
+ }
+
+ BloodLightCrystal: {
+ DisplayName: Blood Light Crystal
+ Tooltip: ""
+ }
+
+ TrueDeathSickle: {
+ DisplayName: True Death Sickle
+ Tooltip: ""
+ }
+
+ LiftLamp: {
+ DisplayName: Lift Lamp
+ Tooltip: ""
+ }
+
+ LiftWinch: {
+ DisplayName: Lift Winch
+ Tooltip: ""
+ }
+
+ HardmodeItem: {
+ DisplayName: Hardmode Item
+ Tooltip: ""
+ }
+
+ SightOfTile: {
+ DisplayName: Sight Of Tile
+ Tooltip: ""
+ }
+
+ TestItem: {
+ DisplayName: Test Item
+ Tooltip: ""
+ }
+}
+
+NPCs: {
+ TuskKillEffect.DisplayName: Tusk Kill Effect
+ TuskWall.DisplayName: Tusk Wall
+ BloodTusk.DisplayName: Blood Tusk
+ BloodyMouth1.DisplayName: Bloody Mouth1
+ BloodyMouth2.DisplayName: Bloody Mouth2
+ CrimsonTusk.DisplayName: Crimson Tusk
+ CrimsonTusk1.DisplayName: Crimson Tusk1
+ CrimsonTuskControlable.DisplayName: Crimson Tusk Controlable
+ CrimsonTuskFireWork.DisplayName: Crimson Tusk Fire Work
+ HugeMouth.DisplayName: Huge Mouth
+ LargeTusk.DisplayName: Large Tusk
+ LargeTusk2.DisplayName: Large Tusk2
+ LittleMouth.DisplayName: Little Mouth
+ LittleTusk.DisplayName: Little Tusk
+ TuskCooling.DisplayName: Tusk Cooling
+ TuskPoolWave.DisplayName: Tusk Pool Wave
+ TuskRedLight.DisplayName: Tusk Red Light
+ TuskWallLeft.DisplayName: Tusk Wall Left
+ TuskWallRight.DisplayName: Tusk Wall Right
+ TuskWave.DisplayName: Tusk Wave
+ TuskWaveHuge.DisplayName: Tusk Wave Huge
+ GlowingHeal.DisplayName: Glowing Heal
+ BlackStarFruit.DisplayName: Black Star Fruit
+ CentipedeHead.DisplayName: Centipede Head
+ CentipedeBody.DisplayName: Centipede Body
+ CentipedeTail.DisplayName: Centipede Tail
+ Dendroid_normal.DisplayName: Dendroid_normal
+ FireflyPiranha.DisplayName: Firefly Piranha
+ FireflyPiranhaInfected.DisplayName: Firefly Piranha Infected
+ FireflyPiranhaInfected_small.DisplayName: Firefly Piranha Infected_small
+ FireflyPiranha_small.DisplayName: Firefly Piranha_small
+ GlowingFirefly.DisplayName: Glowing Firefly
+ LargeFireBulb.DisplayName: Large Fire Bulb
+ LittleFireBulb.DisplayName: Little Fire Bulb
+ Butterfly.DisplayName: Butterfly
+ CorruptMoth.DisplayName: Corrupt Moth
+ EvilPack.DisplayName: Evil Pack
+ MothSummonEffect.DisplayName: Moth Summon Effect
+ FloatLantern.DisplayName: Float Lantern
+ RedPackBomber.DisplayName: Red Pack Bomber
+ LanternGhostKing.DisplayName: Lantern Ghost King
+ BlueCore.DisplayName: Blue Core
+ FlamingDashCore.DisplayName: Flaming Dash Core
+ GreenCore.DisplayName: Green Core
+ RedCore.DisplayName: Red Core
+ YellowCore.DisplayName: Yellow Core
+
+ Acytaea: {
+ DisplayName: Acytaea
+
+ TownNPCMood: {
+ Content: I am content.
+ NoHome: I hate not having a home.
+ FarFromHome: I am too far from home.
+ LoveSpace: I love having so much space.
+ DislikeCrowded: I dislike how crowded I am.
+ HateCrowded: I hate how crowded I am.
+ LikeNPC_Princess: I like {NPCName}.
+ Princess_LovesNPC: I like {NPCName}.
+ }
+ }
+
+ AcytaeaShadow.DisplayName: Acytaea Shadow
+ AcytaeaShadow2.DisplayName: Acytaea Shadow2
+ AcytaeaShadow3.DisplayName: Acytaea Shadow3
+ FakeAcytaea.DisplayName: Fake Acytaea
+ CyanOreBeetle.DisplayName: Cyan Ore Beetle
+ SquamousShell.DisplayName: Squamous Shell
+ TestNPC.DisplayName: Test N P C
+}
+
+Prefixes: {
+ Accurate.DisplayName: Accurate
+ Aimed.DisplayName: Aimed
+}
+
+Projectiles: {
+ BloodGoldBayonet_Pro.DisplayName: Blood Gold Bayonet_ Pro
+ BlueRibbonBayonet_Pro.DisplayName: Blue Ribbon Bayonet_ Pro
+ CopperStabbingSword_Pro.DisplayName: Copper Stabbing Sword_ Pro
+ DreamStar_Explosion.DisplayName: Dream Star_ Explosion
+ DreamStar_Pro.DisplayName: Dream Star_ Pro
+ EnchantedBayonet_Pro.DisplayName: Enchanted Bayonet_ Pro
+ EternalNight_Pro.DisplayName: Eternal Night_ Pro
+ GoldenStabbingSword_Pro.DisplayName: Golden Stabbing Sword_ Pro
+ HolyBayonet_Pro.DisplayName: Holy Bayonet_ Pro
+ IronStabbingSword_Pro.DisplayName: Iron Stabbing Sword_ Pro
+ LeadStabbingSword_Pro.DisplayName: Lead Stabbing Sword_ Pro
+ PlatinumStabbingSword_Pro.DisplayName: Platinum Stabbing Sword_ Pro
+ PrisonFireBayonet_Pro.DisplayName: Prison Fire Bayonet_ Pro
+ RedRibbonBayonet_Pro.DisplayName: Red Ribbon Bayonet_ Pro
+ RottenGoldBayonet_Mark.DisplayName: Rotten Gold Bayonet_ Mark
+ RottenGoldBayonet_Pro.DisplayName: Rotten Gold Bayonet_ Pro
+ RottenGoldBayonet_Slash.DisplayName: Rotten Gold Bayonet_ Slash
+ SilverStabbingSword_Pro.DisplayName: Silver Stabbing Sword_ Pro
+ TinStabbingSword_Pro.DisplayName: Tin Stabbing Sword_ Pro
+ TungstenStabbingSword_Pro.DisplayName: Tungsten Stabbing Sword_ Pro
+ VegetationBayonet_Pro.DisplayName: Vegetation Bayonet_ Pro
+ YoenLeZed_Pro.DisplayName: Yoen Le Zed_ Pro
+ FryingPan.DisplayName: Frying Pan
+ ButterflyDreamFriendly.DisplayName: Butterfly Dream Friendly
+ ButterflyDream.DisplayName: Butterfly Dream
+ DashingLightEff.DisplayName: Dashing Light Eff
+ VortexVanquisher.DisplayName: Vortex Vanquisher
+ VortexVanquisher2.DisplayName: Vortex Vanquisher2
+ VortexVanquisher3.DisplayName: Vortex Vanquisher3
+ VortexVanquisherThump.DisplayName: Vortex Vanquisher Thump
+ GoldShield.DisplayName: Gold Shield
+ StonePost.DisplayName: Stone Post
+ CrimsonTuskProj.DisplayName: Crimson Tusk Proj
+ CrimsonTuskProjGra.DisplayName: Crimson Tusk Proj Gra
+ EarthTusk.DisplayName: Earth Tusk
+ EarthTuskHostile.DisplayName: Earth Tusk Hostile
+ TuskCrack.DisplayName: Tusk Crack
+ TuskCurse.DisplayName: Tusk Curse
+ TuskSpice.DisplayName: Tusk Spice
+ TuskSpiceBlack.DisplayName: Tusk Spice Black
+ TuskSpicePro.DisplayName: Tusk Spice Pro
+ Tusk.DisplayName: Tusk
+ BloodyBoneYoyo.DisplayName: Bloody Bone Yoyo
+ LittleTusk.DisplayName: Little Tusk
+ LittleTusk0.DisplayName: Little Tusk0
+ SpineGun.DisplayName: Spine Gun
+ SplieSpineBullet.DisplayName: Splie Spine Bullet
+ ToothMagic.DisplayName: Tooth Magic
+ ToothMagicBall.DisplayName: Tooth Magic Ball
+ ToothMagicHit.DisplayName: Tooth Magic Hit
+ ToothMagicSplit.DisplayName: Tooth Magic Split
+ ToothMagicSplit2.DisplayName: Tooth Magic Split2
+ ToothSpear.DisplayName: Tooth Spear
+ Tusk0.DisplayName: Tusk0
+ TuskArrow.DisplayName: Tusk Arrow
+ TuskSpear3.DisplayName: Tusk Spear3
+ TuskSpear4.DisplayName: Tusk Spear4
+ TuskSummon.DisplayName: Tusk Summon
+ BeadShakeWave.DisplayName: Bead Shake Wave
+ BlackCorruptRain.DisplayName: Black Corrupt Rain
+ BlackCorruptRain3.DisplayName: Black Corrupt Rain3
+ BlackCorruptRain3Friendly.DisplayName: Black Corrupt Rain3 Friendly
+ BlackCorruptRainFriendly.DisplayName: Black Corrupt Rain Friendly
+ BlueMissil.DisplayName: Blue Missil
+ BlueMissilFriendly.DisplayName: Blue Missil Friendly
+ BombShakeWave.DisplayName: Bomb Shake Wave
+ CorMoth4DProj.DisplayName: Cor Moth4 D Proj
+ CorruptDust.DisplayName: Corrupt Dust
+ DarkEffect.DisplayName: Dark Effect
+ DarkFan.DisplayName: Dark Fan
+ DarkFanFly.DisplayName: Dark Fan Fly
+ DreamWeaver.DisplayName: Dream Weaver
+ EvilChrysalis.DisplayName: Evil Chrysalis
+ EvilChrysalisRightClick.DisplayName: Evil Chrysalis Right Click
+ FanHit.DisplayName: Fan Hit
+ FlowLightMissile.DisplayName: Flow Light Missile
+ FruitBomb.DisplayName: Fruit Bomb
+ GlowBeadGun.DisplayName: Glow Bead Gun
+ GlowBeadGunShootFlame.DisplayName: Glow Bead Gun Shoot Flame
+ GlowingButterfly.DisplayName: Glowing Butterfly
+ GlowMoth.DisplayName: Glow Moth
+ GlowStar.DisplayName: Glow Star
+ GlowStarExplosion.DisplayName: Glow Star Explosion
+ GlowWoodSword.DisplayName: Glow Wood Sword
+ MissileProj.DisplayName: Missile Proj
+ MissileProjHostile.DisplayName: Missile Proj Hostile
+ MothArrow.DisplayName: Moth Arrow
+ MothBall.DisplayName: Moth Ball
+ MothGrey.DisplayName: Moth Grey
+ MothMagicArray.DisplayName: Moth Magic Array
+ MothYoyoProjectile.DisplayName: Moth Yoyo Projectile
+ MothYoyoSub.DisplayName: Moth Yoyo Sub
+ NavyThunder.DisplayName: Navy Thunder
+ NavyThunderBomb.DisplayName: Navy Thunder Bomb
+ PhantomMoth.DisplayName: Phantom Moth
+ PhosphorescenceBullet.DisplayName: Phosphorescence Bullet
+ PhosphorescenceGun.DisplayName: Phosphorescence Gun
+ ScaleWingBladeProj.DisplayName: Scale Wing Blade Proj
+ ShadowWingBow.DisplayName: Shadow Wing Bow
+ StaffOfCorruptDust.DisplayName: Staff Of Corrupt Dust
+ LilyHarpNote.DisplayName: Lily Harp Note
+ LilyHarpNoteKill.DisplayName: Lily Harp Note Kill
+ LilyHarpProj.DisplayName: Lily Harp Proj
+ LilyHarpWave.DisplayName: Lily Harp Wave
+ VineProj.DisplayName: Vine Proj
+ VineProj2.DisplayName: Vine Proj2
+ CloudBall.DisplayName: Cloud Ball
+ MagicHit.DisplayName: Magic Hit
+ AshBone.DisplayName: Ash Bone
+ XmasWhip.DisplayName: Xmas Whip
+ AmbiguousLine.DisplayName: Ambiguous Line
+ AmbiguousNight.DisplayName: Ambiguous Night
+ AmbiguousNightAmmo.DisplayName: Ambiguous Night Ammo
+ AmbiguousNightHit.DisplayName: Ambiguous Night Hit
+ AmethystBead.DisplayName: Amethyst Bead
+ AmethystSlingshot.DisplayName: Amethyst Slingshot
+ BorealWoodSlingshot.DisplayName: Boreal Wood Slingshot
+ CactusSlingShot.DisplayName: Cactus Sling Shot
+ DiamondBead.DisplayName: Diamond Bead
+ DiamondSlingshot.DisplayName: Diamond Slingshot
+ EbonwoodSlingshot.DisplayName: Ebonwood Slingshot
+ EmeraldBead.DisplayName: Emerald Bead
+ EmeraldSlingshot.DisplayName: Emerald Slingshot
+ GelBall.DisplayName: Gel Ball
+ GelSlingshot.DisplayName: Gel Slingshot
+ GlowSporeBead.DisplayName: Glow Spore Bead
+ JungleSlingshot.DisplayName: Jungle Slingshot
+ JungleSlingshotHit.DisplayName: Jungle Slingshot Hit
+ KSSlingshotHit.DisplayName: K S Slingshot Hit
+ KSSlingshotHitPink.DisplayName: K S Slingshot Hit Pink
+ NormalAmmo.DisplayName: Normal Ammo
+ NormalHit.DisplayName: Normal Hit
+ PalmWoodSlingshot.DisplayName: Palm Wood Slingshot
+ PearlwoodSlingshot.DisplayName: Pearlwood Slingshot
+ RichMahoganySlingshot.DisplayName: Rich Mahogany Slingshot
+ RubyBead.DisplayName: Ruby Bead
+ RubySlingshot.DisplayName: Ruby Slingshot
+ SapphireBead.DisplayName: Sapphire Bead
+ SapphireSlingshot.DisplayName: Sapphire Slingshot
+ ShadewoodSlingShot.DisplayName: Shadewood Sling Shot
+ StarAmmo.DisplayName: Star Ammo
+ StarSlingshot.DisplayName: Star Slingshot
+ TopazBead.DisplayName: Topaz Bead
+ TopazSlingshot.DisplayName: Topaz Slingshot
+ WoodSlingshot.DisplayName: Wood Slingshot
+ ComingGhost.DisplayName: Coming Ghost
+ ComingGhost2.DisplayName: Coming Ghost2
+ GhostHit.DisplayName: Ghost Hit
+ GoldRound.DisplayName: Gold Round
+ GoldRoundYoyo.DisplayName: Gold Round Yoyo
+ MeleeHit.DisplayName: Melee Hit
+ MeleeHit2.DisplayName: Melee Hit2
+ Sunflower.DisplayName: Sunflower
+ SunFlowerpetal.DisplayName: Sun Flowerpetal
+ World.DisplayName: World
+ WorldHit.DisplayName: World Hit
+ Hepuyuan.DisplayName: Hepuyuan
+ HepuyuanDown.DisplayName: Hepuyuan Down
+ HepuyuanShake.DisplayName: Hepuyuan Shake
+ HepuyuanSpice.DisplayName: Hepuyuan Spice
+ XiaoBlackWave.DisplayName: Xiao Black Wave
+ XiaoHit.DisplayName: Xiao Hit
+ AdamantiteClub.DisplayName: Adamantite Club
+ BorealWoodClub.DisplayName: Boreal Wood Club
+ CactusClub.DisplayName: Cactus Club
+ ChlorophyteClub.DisplayName: Chlorophyte Club
+ ChlorophyteClub_fly.DisplayName: Chlorophyte Club_fly
+ ChlorophyteClub_VFX.DisplayName: Chlorophyte Club_ V F X
+ CobaltClub.DisplayName: Cobalt Club
+ CopperClub.DisplayName: Copper Club
+ CorruptClub.DisplayName: Corrupt Club
+ CrimsonClub.DisplayName: Crimson Club
+ CrystalClub.DisplayName: Crystal Club
+ CrystalClub_fly.DisplayName: Crystal Club_fly
+ CurseClub.DisplayName: Curse Club
+ CurseClub_fly.DisplayName: Curse Club_fly
+ EbonwoodClub.DisplayName: Ebonwood Club
+ GoldClub.DisplayName: Gold Club
+ IchorClub.DisplayName: Ichor Club
+ IchorClub_fly.DisplayName: Ichor Club_fly
+ IronClub.DisplayName: Iron Club
+ LeadClub.DisplayName: Lead Club
+ MeteorClub.DisplayName: Meteor Club
+ MithrilClub.DisplayName: Mithril Club
+ OrichalcumClub.DisplayName: Orichalcum Club
+ PalladiumClub.DisplayName: Palladium Club
+ PalmWoodClub.DisplayName: Palm Wood Club
+ PearlwoodClub.DisplayName: Pearlwood Club
+ PlatinumClub.DisplayName: Platinum Club
+ RichMahoganyClub.DisplayName: Rich Mahogany Club
+ ShadewoodClub.DisplayName: Shadewood Club
+ SilverClub.DisplayName: Silver Club
+ SpikeClub.DisplayName: Spike Club
+ StarDancer.DisplayName: Star Dancer
+ TinClub.DisplayName: Tin Club
+ TitaniumClub.DisplayName: Titanium Club
+ TungstenClub.DisplayName: Tungsten Club
+ WoodenClub.DisplayName: Wooden Club
+ BoneFeather.DisplayName: Bone Feather
+ EndlessCurseFlame.DisplayName: Endless Curse Flame
+ FireFeather.DisplayName: Fire Feather
+ FreezeFeather.DisplayName: Freeze Feather
+ ThunderBall.DisplayName: Thunder Ball
+ ThunderBall2.DisplayName: Thunder Ball2
+ ThunderBallToNPC.DisplayName: Thunder Ball To N P C
+ FreezeFeatherMagicArray.DisplayName: Freeze Feather Magic Array
+ FreezeFeatherMagicBook.DisplayName: Freeze Feather Magic Book
+ FreezeShoot.DisplayName: Freeze Shoot
+ GiantFreezeFeather.DisplayName: Giant Freeze Feather
+ GiantFreezeFeatherExplosion.DisplayName: Giant Freeze Feather Explosion
+ FireFeatherMagicArray.DisplayName: Fire Feather Magic Array
+ FireFeatherMagicBook.DisplayName: Fire Feather Magic Book
+ FlameShoot.DisplayName: Flame Shoot
+ GiantFireFeather.DisplayName: Giant Fire Feather
+ GiantFireFeatherExplosion.DisplayName: Giant Fire Feather Explosion
+ FlowerPetalPurple.DisplayName: Flower Petal Purple
+ PurpleBallEffect.DisplayName: Purple Ball Effect
+ FixCoinCrit1.DisplayName: Fix Coin Crit1
+ FixCoinCrit2.DisplayName: Fix Coin Crit2
+ FixCoinCrit3.DisplayName: Fix Coin Crit3
+ FixCoinCrit4.DisplayName: Fix Coin Crit4
+ FixCoinCrit5.DisplayName: Fix Coin Crit5
+ FixCoinDamage1.DisplayName: Fix Coin Damage1
+ FixCoinDamage2.DisplayName: Fix Coin Damage2
+ FixCoinDamage3.DisplayName: Fix Coin Damage3
+ FixCoinDamage4.DisplayName: Fix Coin Damage4
+ FixCoinDamage5.DisplayName: Fix Coin Damage5
+ FixCoinDefense1.DisplayName: Fix Coin Defense1
+ FixCoinDefense2.DisplayName: Fix Coin Defense2
+ FixCoinDefense3.DisplayName: Fix Coin Defense3
+ FixCoinDefense4.DisplayName: Fix Coin Defense4
+ FixCoinDefense5.DisplayName: Fix Coin Defense5
+ FixCoinMelee1.DisplayName: Fix Coin Melee1
+ FixCoinMelee2.DisplayName: Fix Coin Melee2
+ FixCoinMelee3.DisplayName: Fix Coin Melee3
+ FixCoinSpeed1.DisplayName: Fix Coin Speed1
+ FixCoinSpeed2.DisplayName: Fix Coin Speed2
+ FixCoinSpeed3.DisplayName: Fix Coin Speed3
+ IchorRing.DisplayName: Ichor Ring
+ NewWaterBolt.DisplayName: New Water Bolt
+ WaterBoltArray.DisplayName: Water Bolt Array
+ WaterBoltBook.DisplayName: Water Bolt Book
+ WaterTeleport.DisplayName: Water Teleport
+ HurricaneMask.DisplayName: Hurricane Mask
+ RazorbladeTyphoonArray.DisplayName: Razorblade Typhoon Array
+ RazorbladeTyphoonBook.DisplayName: Razorblade Typhoon Book
+ TyphoonII.DisplayName: Typhoon I I
+ MagnetSphereArray.DisplayName: Magnet Sphere Array
+ MagnetSphereBook.DisplayName: Magnet Sphere Book
+ MagnetSphereHit.DisplayName: Magnet Sphere Hit
+ MagnetSphereII.DisplayName: Magnet Sphere I I
+ MagnetSphereLighting.DisplayName: Magnet Sphere Lighting
+ LunarFlareArray.DisplayName: Lunar Flare Array
+ LunarFlareBook.DisplayName: Lunar Flare Book
+ LunarFlareHit.DisplayName: Lunar Flare Hit
+ LunarFlareII.DisplayName: Lunar Flare I I
+ StarProj.DisplayName: Star Proj
+ GoldenShowerArray.DisplayName: Golden Shower Array
+ GoldenShowerBomb.DisplayName: Golden Shower Bomb
+ GoldenShowerBook.DisplayName: Golden Shower Book
+ GoldenShowerII.DisplayName: Golden Shower I I
+ DreamWeaverBook.DisplayName: Dream Weaver Book
+ DreamWeaverII.DisplayName: Dream Weaver I I
+ DemoHit.DisplayName: Demo Hit
+ DemonScytheArray.DisplayName: Demon Scythe Array
+ DemonScytheBook.DisplayName: Demon Scythe Book
+ DemonScythePlus.DisplayName: Demon Scythe Plus
+ DemonScythePlusCrack.DisplayName: Demon Scythe Plus Crack
+ DemoSpark.DisplayName: Demo Spark
+ CursedFlameHit.DisplayName: Cursed Flame Hit
+ CursedFlamesArray.DisplayName: Cursed Flames Array
+ CursedFlamesBook.DisplayName: Cursed Flames Book
+ CursedFlamesII.DisplayName: Cursed Flames I I
+ CrystalStormArray.DisplayName: Crystal Storm Array
+ CrystalStormBook.DisplayName: Crystal Storm Book
+ CrystalStormII.DisplayName: Crystal Storm I I
+ CrystalWind.DisplayName: Crystal Wind
+ LargeCrystal.DisplayName: Large Crystal
+ Storm.DisplayName: Storm
+ BoneSpike.DisplayName: Bone Spike
+ BookofSkullsArray.DisplayName: Bookof Skulls Array
+ BookofSkullsBook.DisplayName: Bookof Skulls Book
+ SkullHand.DisplayName: Skull Hand
+ SkullII.DisplayName: Skull I I
+ BlackHole.DisplayName: Black Hole
+ BloodLampProj.DisplayName: Blood Lamp Proj
+ LBloodEffect.DisplayName: L Blood Effect
+ LBloodEffectGra.DisplayName: L Blood Effect Gra
+ LMeteor.DisplayName: L Meteor
+ RainbowWave.DisplayName: Rainbow Wave
+ DarkLantern.DisplayName: Dark Lantern
+ DarkLantern3.DisplayName: Dark Lantern3
+ DarkLanternBomb2.DisplayName: Dark Lantern Bomb2
+ DarkLanternBombExplosion.DisplayName: Dark Lantern Bomb Explosion
+ DarkLanternBombExplosion_II.DisplayName: Dark Lantern Bomb Explosion_ I I
+ ExplodeLantern.DisplayName: Explode Lantern
+ floatLantern.DisplayName: float Lantern
+ floatLantern2.DisplayName: float Lantern2
+ floatLantern3.DisplayName: float Lantern3
+ floatLantern4.DisplayName: float Lantern4
+ floatLantern5.DisplayName: float Lantern5
+ GoldLantern.DisplayName: Gold Lantern
+ GoldLanternLine.DisplayName: Gold Lantern Line
+ GoldLanternLine2.DisplayName: Gold Lantern Line2
+ GoldLanternLine3.DisplayName: Gold Lantern Line3
+ GoldLanternLine4.DisplayName: Gold Lantern Line4
+ GoldLanternLine5.DisplayName: Gold Lantern Line5
+ GoldLanternLine6.DisplayName: Gold Lantern Line6
+ GoldLanternLine7.DisplayName: Gold Lantern Line7
+ GoldLanternLine8.DisplayName: Gold Lantern Line8
+ GoldLanternRay.DisplayName: Gold Lantern Ray
+ GoldLanternStar.DisplayName: Gold Lantern Star
+ Redlight.DisplayName: Redlight
+ StrikePlayer.DisplayName: Strike Player
+ BlueFlame0.DisplayName: Blue Flame0
+ BlueFlame0Little.DisplayName: Blue Flame0 Little
+ BlueFlame0LittleSoon.DisplayName: Blue Flame0 Little Soon
+ BlueFlame1Boom.DisplayName: Blue Flame1 Boom
+ BlueStarTrail.DisplayName: Blue Star Trail
+ BrownFlame0.DisplayName: Brown Flame0
+ BrownFlame0Little.DisplayName: Brown Flame0 Little
+ GoldDashLine.DisplayName: Gold Dash Line
+ GreenFlame0.DisplayName: Green Flame0
+ GreenFlame0Little.DisplayName: Green Flame0 Little
+ GreenFlame0Split.DisplayName: Green Flame0 Split
+ GreenFlame1Split.DisplayName: Green Flame1 Split
+ ImmuneCircle.DisplayName: Immune Circle
+ PinkFlame0.DisplayName: Pink Flame0
+ PinkFlame0Little.DisplayName: Pink Flame0 Little
+ PurpleFlame0.DisplayName: Purple Flame0
+ PurpleFlame0Little.DisplayName: Purple Flame0 Little
+ PurpleGreenFlame0.DisplayName: Purple Green Flame0
+ PurpleGreenFlame0Little.DisplayName: Purple Green Flame0 Little
+ RedFlame0.DisplayName: Red Flame0
+ RedFlame0Little.DisplayName: Red Flame0 Little
+ RedFlame0Split.DisplayName: Red Flame0 Split
+ RedFlame1Split.DisplayName: Red Flame1 Split
+ RedFlame2Split.DisplayName: Red Flame2 Split
+ YellowFlame0.DisplayName: Yellow Flame0
+ YellowFlame0Little.DisplayName: Yellow Flame0 Little
+ YellowFlame0LittleShine.DisplayName: Yellow Flame0 Little Shine
+ YellowFlame0Shine.DisplayName: Yellow Flame0 Shine
+ YellowToRedFlame0Little.DisplayName: Yellow To Red Flame0 Little
+ AcytaeaArrow.DisplayName: Acytaea Arrow
+ AcytaeaArrow2.DisplayName: Acytaea Arrow2
+ AcytaeaArrow3.DisplayName: Acytaea Arrow3
+ AcytaeaArrowGra.DisplayName: Acytaea Arrow Gra
+ AcytaeaBow.DisplayName: Acytaea Bow
+ AcytaeaBow2.DisplayName: Acytaea Bow2
+ AcytaeaCenterBow.DisplayName: Acytaea Center Bow
+ AcytaeaEffect.DisplayName: Acytaea Effect
+ AcytaeaEffectUp.DisplayName: Acytaea Effect Up
+ AcytaeaLaser.DisplayName: Acytaea Laser
+ AcytaeaLaserBall.DisplayName: Acytaea Laser Ball
+ AcytaeaLaserLight.DisplayName: Acytaea Laser Light
+ AcytaeaLight.DisplayName: Acytaea Light
+ AcytaeaMagicBook.DisplayName: Acytaea Magic Book
+ AcytaeaTornado.DisplayName: Acytaea Tornado
+ AcytaeaTornado2.DisplayName: Acytaea Tornado2
+ AcytaeaTornado3.DisplayName: Acytaea Tornado3
+ AcytaeaTornado4.DisplayName: Acytaea Tornado4
+ AcytaeaTornado5.DisplayName: Acytaea Tornado5
+ AcytaeaTornadoHit.DisplayName: Acytaea Tornado Hit
+ AcytaeaWarningArrow.DisplayName: Acytaea Warning Arrow
+ BloodBlade.DisplayName: Blood Blade
+ BloodBlade2.DisplayName: Blood Blade2
+ BloodBladeShadow.DisplayName: Blood Blade Shadow
+ BrokenAcytaea.DisplayName: Broken Acytaea
+ BrokenAcytaea2.DisplayName: Broken Acytaea2
+ Metero.DisplayName: Metero
+ Metero2.DisplayName: Metero2
+ Metero3.DisplayName: Metero3
+ Metero4.DisplayName: Metero4
+ MeteroFri.DisplayName: Metero Fri
+ playerHit.DisplayName: player Hit
+ CactusBallProj.DisplayName: Cactus Ball Proj
+ CactusBallSpike.DisplayName: Cactus Ball Spike
+ CyanVineThrowingSpear.DisplayName: Cyan Vine Throwing Spear
+ AcroporaSpear.DisplayName: Acropora Spear
+ AcroporaThumpEff.DisplayName: Acropora Thump Eff
+ TrueDeathSickle.DisplayName: True Death Sickle
+ TrueDeathSickleHit.DisplayName: True Death Sickle Hit
+ SightOfTileProj.DisplayName: Sight Of Tile Proj
+ SightOfTileProjRead.DisplayName: Sight Of Tile Proj Read
+}
+
+Configs: {
+ EverglowConfig: {
+ DisplayName: Everglow Config
+
+ debugMode: {
+ Label: Enable Debug Mode
+ Tooltip: "[For developers] Enable debug mode to allow debug functions to run"
+ }
+ }
+
+ EverglowClientConfig: {
+ DisplayName: Everglow Client Config
+
+ TextureReplace: {
+ Label: "{$Mods.Everglow.Config.TextureReplace.Label}"
+ Tooltip: "{$Mods.Everglow.Config.TextureReplace.Tooltip}"
+ }
+
+ ItemPickSoundReplace: {
+ Label: "{$Mods.Everglow.Config.ItemPickSoundReplace.Label}"
+ Tooltip: ""
+ }
+
+ MothAudioReplace: {
+ Label: "{$Mods.Everglow.Config.MothAudioReplace.Label}"
+ Tooltip: "{$Mods.Everglow.Config.MothAudioReplace.Tooltip}"
+ }
+
+ TuskAudioReplace: {
+ Label: "{$Mods.Everglow.Config.TuskAudioReplace.Label}"
+ Tooltip: "{$Mods.Everglow.Config.TuskAudioReplace.Tooltip}"
+ }
+ }
+
+ TextureReplaceMode: {
+ Tooltip: ""
+ Terraria.Label: Terraria
+ EternalResolve.Label: Eternal Resolve
+ Myth.Label: Myth
+ }
+
+ MothAudioReplaceMode: {
+ Tooltip: ""
+ MothFighting.Label: Original
+ AltMothFighting.Label: Alternate
+ OldMothFighting.Label: Old
+ }
+
+ TuskAudioReplaceMode: {
+ Tooltip: ""
+ TuskFighting.Label: Original
+ OldTuskFighting.Label: Old
+ }
+
+ FogConfigs: {
+ DisplayName: Fog Configs
+
+ EnableScattering: {
+ Label: 开启雾效
+ Tooltip: 是否开启参与介质散射
+ }
+
+ EnableLightUpload: {
+ Label: 【性能测试】开启光源数据
+ Tooltip: 是否启用发光体数据上传(CPU到GPU)
+ }
+
+ MaxBloomRadius: {
+ Label: 模糊半径
+ Tooltip: 光效的最大溢出半径,最终半径是以2为底的指数,越大越影响性能
+ }
+
+ BloomIntensity: {
+ Label: 光效强度
+ Tooltip: 光效的强度,用于放大亮度
+ }
+
+ OffscreenTiles: {
+ Label: 离屏物块渲染数量
+ Tooltip: 光效需要计算超出屏幕的物块数量
+ }
+
+ LightLuminanceThreashold: {
+ Label: 光源阈值
+ Tooltip: 可以调整原版点亮物块的光源阈值
+ }
+
+ GaussianKernel: {
+ Label: 是否开启高斯卷积核
+ Tooltip: 更柔和的效果,但是性能较差
+ }
+
+ FogAbsorptionR: {
+ Label: 雾吸收率(R)
+ Tooltip: 雾吸收红色通道直接光的比率,越大则越暗淡
+ }
+
+ FogAbsorptionG: {
+ Label: 雾吸收率(G)
+ Tooltip: 雾吸收绿色通道直接光的比率,越大则越暗淡
+ }
+
+ FogAbsorptionB: {
+ Label: 雾吸收率(B)
+ Tooltip: 雾吸收蓝色通道直接光的比率,越大则越暗淡
+ }
+
+ FogScatterWithDistance: {
+ Label: 扩散率随距离增大
+ Tooltip: 是否让散射效果随着距离增大而增大
+ }
+
+ FogBloomRate: {
+ Label: 雾散射扩散率
+ Tooltip: 散射光的扩散比率
+ }
+
+ FogBloomAbsorptionFactor: {
+ Label: 雾散射能见度影响系数
+ Tooltip: 散射光受到能见度影响的比率,0为不受能见度影响,1完全受能见度影响
+ }
+
+ EnableTemporalInterp: {
+ Label: 开启Temporal插值
+ Tooltip: 是否允许光照结果进行帧间插值来平滑
+ }
+ }
+}
+
+Config: {
+ Header: {
+ TextureReplace: Texture Replace Header
+ AudioReplace: Item Pick Sound Replace Header
+ }
+}
\ No newline at end of file
diff --git a/Sources/Everglow.Core/Everglow.Core.csproj b/Sources/Everglow.Core/Everglow.Core.csproj
index 9a8d2552b..b29ccf7d7 100644
--- a/Sources/Everglow.Core/Everglow.Core.csproj
+++ b/Sources/Everglow.Core/Everglow.Core.csproj
@@ -6,9 +6,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs
new file mode 100644
index 000000000..6ced81e82
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision
+{
+ public struct AABB
+ {
+ public Vector2 MinPoint;
+ public Vector2 MaxPoint;
+
+ public bool Intersects(in AABB other)
+ {
+ return Math.Max(MinPoint.X, other.MinPoint.X) <= Math.Min(MaxPoint.X, other.MaxPoint.X)
+ && Math.Max(MinPoint.Y, other.MinPoint.Y) <= Math.Min(MaxPoint.Y, other.MaxPoint.Y);
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs
new file mode 100644
index 000000000..c18773689
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs
@@ -0,0 +1,115 @@
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
+{
+ ///
+ /// 暴力遍历AABB的粗粒度碰撞检测算法
+ ///
+ public class BruteForceDetect : BroadPhase
+ {
+ private struct BruteForceEntry
+ {
+ public int ColliderId;
+ public AABB BoundingBox;
+ public bool IsDynamic;
+ }
+ private List _colliders;
+ private Dictionary> _groups;
+ public BruteForceDetect(CollisionGraph graph) : base(graph)
+ {
+ _colliders = new List();
+ _groups = new Dictionary>();
+ }
+
+ private void GroupInnerDetection(List entries,
+ List> collisionResults)
+ {
+ for (int i = 0; i < entries.Count; i++)
+ {
+ for (int j = i + 1; j < entries.Count; j++)
+ {
+ if ((entries[i].IsDynamic || entries[j].IsDynamic)
+ && entries[i].BoundingBox.Intersects(entries[j].BoundingBox))
+ {
+ collisionResults.Add(new KeyValuePair(_colliders[entries[i].ColliderId],
+ _colliders[entries[j].ColliderId]));
+ }
+ }
+ }
+ }
+
+ private void GroupOuterDetection(List groupA,
+ List groupB,
+ List> collisionResults)
+ {
+ for (int i = 0; i < groupA.Count; i++)
+ {
+ for (int j = 0; j < groupB.Count; j++)
+ {
+ if ((groupA[i].IsDynamic || groupB[j].IsDynamic)
+ && groupA[i].BoundingBox.Intersects(groupB[j].BoundingBox))
+ {
+ collisionResults.Add(new KeyValuePair(_colliders[groupA[i].ColliderId],
+ _colliders[groupB[j].ColliderId]));
+ }
+ }
+ }
+ }
+
+ public override List> GetCollisionPairs(float deltaTime)
+ {
+ List> finalPairs = new List>();
+ foreach(var group in _groups)
+ {
+ var thisgroup = _groups[group.Key];
+ GroupInnerDetection(thisgroup, finalPairs);
+ if (_collisionGraph.Graph.ContainsKey(group.Key))
+ {
+ foreach (var dual in _collisionGraph.Graph[group.Key])
+ {
+ if (!_groups.ContainsKey(dual))
+ continue;
+ GroupOuterDetection(thisgroup, _groups[dual], finalPairs);
+ }
+ }
+ }
+ return finalPairs;
+ }
+
+ public override void Prepare(List objects, float deltaTime)
+ {
+ _colliders.Clear();
+ _colliders.EnsureCapacity(objects.Count);
+ _groups.Clear();
+ for(int i = 0; i < objects.Count; i++)
+ {
+ var obj = objects[i];
+ _colliders.Add(obj.Collider);
+ var entry = new BruteForceEntry()
+ {
+ ColliderId = i,
+ BoundingBox = obj.Collider.GetAABB(deltaTime),
+ IsDynamic = obj.RigidBody.MovementType == MovementType.Dynamic || obj.RigidBody.MovementType == MovementType.Player
+ };
+
+ if (_groups.ContainsKey(obj.Tag))
+ {
+ _groups[obj.Tag].Add(entry);
+ }
+ else
+ {
+ _groups.Add(obj.Tag, new List()
+ {
+ entry
+ });
+ }
+ }
+ }
+
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs
new file mode 100644
index 000000000..5a3183227
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
+{
+ ///
+ /// 存储碰撞组的碰撞关系的图结构
+ ///
+ public class CollisionGraph
+ {
+ public static CollisionGraph DefualtGraph
+ = new CollisionGraph(new Dictionary>() { { "Default", new List() } });
+ public Dictionary> Graph
+ {
+ get;
+ set;
+ }
+
+ public CollisionGraph()
+ {
+ Graph = new Dictionary>();
+ }
+
+ public CollisionGraph(Dictionary> graph)
+ {
+ Graph = graph;
+ }
+
+ public void AddDoubleEdge(string groupA, string groupB)
+ {
+ if (groupA == groupB)
+ return;
+ // Ensure only compare once
+ if (String.CompareOrdinal(groupA, groupB) < 0)
+ {
+ AddSingleEdge(groupA, groupB);
+ }
+ else
+ {
+ AddSingleEdge(groupB, groupA);
+ }
+ }
+
+ public void AddSingleEdge(string groupA, string groupB)
+ {
+ if (groupA == groupB)
+ return;
+ if (Graph.ContainsKey(groupA))
+ {
+ Graph[groupA].Add(groupB);
+ }
+ else
+ {
+ Graph.Add(groupA, new List()
+ {
+ groupB
+ });
+ }
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/IBroadPhase.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/IBroadPhase.cs
new file mode 100644
index 000000000..0ec4116e7
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/IBroadPhase.cs
@@ -0,0 +1,24 @@
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
+{
+ ///
+ /// 粗粒度碰撞检测的基类
+ ///
+ public abstract class BroadPhase
+ {
+ protected CollisionGraph _collisionGraph;
+ public BroadPhase(CollisionGraph graph)
+ {
+ _collisionGraph = graph;
+ }
+ public abstract void Prepare(List dynamicObjects, float deltaTime);
+
+ public abstract List> GetCollisionPairs(float deltaTime);
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/SweepAndPrune.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/SweepAndPrune.cs
new file mode 100644
index 000000000..7a888255e
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/SweepAndPrune.cs
@@ -0,0 +1,143 @@
+//using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+//using System;
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Text;
+//using System.Threading.Tasks;
+
+//namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
+//{
+// internal class SweepAndPrune : IBroadPhase
+// {
+// private struct IntervalPoint
+// {
+// public float V;
+// public bool IsEnd;
+// public int ColliderId;
+// }
+
+// private List _pointsX;
+// private List _pointsY;
+// private List _colliders;
+
+// public SweepAndPrune()
+// {
+// _pointsX = new List();
+// _pointsY = new List();
+// _colliders = new List();
+// }
+// public List> GetCollisionPairs(float deltaTime)
+// {
+// List> finalPairs = new List>();
+// HashSet> spottedPairs = new HashSet>();
+// HashSet current = new HashSet();
+// for (int i = 0; i < _pointsX.Count; i++)
+// {
+// var pt = _pointsX[i];
+// if (pt.IsEnd)
+// {
+// foreach (var c in current)
+// {
+// if (c == pt.ColliderId)
+// continue;
+// var p = new KeyValuePair(pt.ColliderId, c);
+
+// if (_colliders[p.Key].ParentObject.RigidBody.MovementType == MovementType.Static
+// && _colliders[p.Value].ParentObject.RigidBody.MovementType == MovementType.Static)
+// {
+// continue;
+// }
+// spottedPairs.Add(p);
+// }
+// current.Remove(pt.ColliderId);
+// }
+// else
+// {
+// current.Add(pt.ColliderId);
+// }
+// }
+
+// current.Clear();
+
+// for (int i = 0; i < _pointsY.Count; i++)
+// {
+// var pt = _pointsY[i];
+// if (pt.IsEnd)
+// {
+// foreach (var c in current)
+// {
+// if (c == pt.ColliderId)
+// continue;
+// var p = new KeyValuePair(pt.ColliderId, c);
+// if (spottedPairs.Contains(p)
+// || spottedPairs.Contains(new KeyValuePair(c, pt.ColliderId)))
+// {
+// if (_colliders[p.Key].ParentObject.RigidBody.MovementType == MovementType.Static
+// && _colliders[p.Value].ParentObject.RigidBody.MovementType == MovementType.Static)
+// {
+// continue;
+// }
+// finalPairs.Add(new KeyValuePair(_colliders[p.Key], _colliders[p.Value]));
+// }
+// }
+// current.Remove(pt.ColliderId);
+// }
+// else
+// {
+// current.Add(pt.ColliderId);
+// }
+// }
+// return finalPairs;
+// }
+
+// public void Prepare(List dynamicObjects, List staticObjects, float deltaTime)
+// {
+// _pointsX.Clear();
+// _pointsY.Clear();
+// _colliders.Clear();
+// _colliders.EnsureCapacity(dynamicObjects.Count + staticObjects.Count);
+// for (int i = 0; i < dynamicObjects.Count; i++)
+// {
+// var obj = dynamicObjects[i];
+// var aabb = obj.Collider.GetAABB(deltaTime);
+// _pointsX.Add(new IntervalPoint() { V = aabb.MinPoint.X, IsEnd = false, ColliderId = i });
+// _pointsX.Add(new IntervalPoint() { V = aabb.MaxPoint.X, IsEnd = true, ColliderId = i });
+// _pointsY.Add(new IntervalPoint() { V = aabb.MinPoint.Y, IsEnd = false, ColliderId = i });
+// _pointsY.Add(new IntervalPoint() { V = aabb.MaxPoint.Y, IsEnd = true, ColliderId = i });
+// _colliders.Add(obj.Collider);
+// }
+
+// for (int i = 0; i < staticObjects.Count; i++)
+// {
+// var obj = staticObjects[i];
+// var aabb = obj.Collider.GetAABB(deltaTime);
+// int id = staticObjects.Count + i;
+// _pointsX.Add(new IntervalPoint() { V = aabb.MinPoint.X, IsEnd = false, ColliderId = id });
+// _pointsX.Add(new IntervalPoint() { V = aabb.MaxPoint.X, IsEnd = true, ColliderId = id });
+// _pointsY.Add(new IntervalPoint() { V = aabb.MinPoint.Y, IsEnd = false, ColliderId = id });
+// _pointsY.Add(new IntervalPoint() { V = aabb.MaxPoint.Y, IsEnd = true, ColliderId = id });
+// _colliders.Add(obj.Collider);
+// }
+
+// Comparison cmp = (a, b) =>
+// {
+// int c = a.V.CompareTo(b.V);
+// if (c == 0)
+// {
+// if (a.IsEnd && !b.IsEnd)
+// {
+// return -1;
+// }
+// if (!a.IsEnd && b.IsEnd)
+// {
+// return 1;
+// }
+// return 0;
+// }
+// return c;
+// };
+// _pointsX.Sort(cmp);
+// _pointsY.Sort(cmp);
+// }
+// }
+//}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/BoxCollider.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/BoxCollider.cs
new file mode 100644
index 000000000..9ce31289c
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/BoxCollider.cs
@@ -0,0 +1,489 @@
+using Everglow.Commons.Physics.PBEngine.GameInteraction;
+using Everglow.Commons.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria;
+using static Terraria.ModLoader.PlayerDrawLayer;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.Colliders
+{
+ ///
+ /// 四边形、盒子碰撞体
+ ///
+ public class BoxCollider : Collider2D
+ {
+ public Vector2 Size
+ {
+ get => new Vector2(_width, _height);
+ }
+ private float _width;
+ private float _height;
+ public BoxCollider(float width, float height)
+ {
+ _width = width;
+ _height = height;
+ }
+
+ public override double InertiaTensor(float mass)
+ {
+ return mass / 12.0 * (_width * _width + _height * _height);
+ }
+
+ public override List GetWireFrameWires()
+ {
+ List wires = new List
+ {
+ new Vector2(-_width / 2, -_height / 2),
+ new Vector2(_width / 2, -_height / 2),
+ new Vector2(_width / 2, -_height / 2),
+ new Vector2(_width / 2, _height / 2),
+ new Vector2(_width / 2, _height / 2),
+ new Vector2(-_width / 2, _height / 2),
+ new Vector2(-_width / 2, _height / 2),
+ new Vector2(-_width / 2, -_height / 2)
+ };
+ return wires;
+ }
+
+ public List GetEdges(float dt)
+ {
+ List cornerWorldSpace = GetCornerPoints(dt);
+ List edges = new List();
+ for (int i = 0; i < 4; i++)
+ {
+ edges.Add(new Edge2D(cornerWorldSpace[i], cornerWorldSpace[(i + 1) % cornerWorldSpace.Count]));
+ }
+ return edges;
+
+ }
+
+ //public override List GetCollisionEvents(Collider2D other, float deltaTime)
+ //{
+ // List events = new List();
+
+ // Vector2[] localPoints = new Vector2[4]
+ // {
+ // new Vector2(-_width / 2, -_height / 2),
+ // new Vector2(_width / 2, -_height / 2),
+ // new Vector2(_width / 2, _height / 2),
+ // new Vector2(-_width / 2, _height / 2)
+ // };
+ // if (other is AABBCollider)
+ // {
+ // AABBCollider aabb_other = (AABBCollider)other;
+ // for (int i = 0; i < 4; i++)
+ // {
+ // var curPos = _bindObject.Position + Matrix2x2.CreateRotationMatrix(_bindObject.Rotation).Multiply(localPoints[i]);
+ // var oldPos = _bindObject.OldPosition + Matrix2x2.CreateRotationMatrix(_bindObject.OldRotation).Multiply(localPoints[i]);
+
+ // foreach (var edge in aabb_other.GetEdges())
+ // {
+ // CollisionEvent2D collision;
+ // if (edge.Segment_Segment_Collision(oldPos, curPos, out collision))
+ // {
+ // collision.Source = this.ParentObject;
+ // collision.Target = other.ParentObject;
+ // collision.LocalOffsetSrc = Matrix2x2.CreateRotationMatrix(_bindObject.Rotation).Multiply(localPoints[i]);
+
+ // events.Add(collision);
+ // }
+ // }
+ // }
+ // }
+ // if (events.Count > 1)
+ // {
+ // Vector2 averagedLocalPoint = new Vector2(0, 0);
+ // Vector2 averagedNormal = new Vector2(0, 0);
+ // float minTime = 1.0f;
+ // for (int i = 0; i < events.Count; i++)
+ // {
+ // averagedLocalPoint += events[i].LocalOffsetSrc;
+ // averagedNormal += events[i].Normal;
+ // minTime = Math.Min(minTime, events[i].Time);
+ // }
+ // averagedLocalPoint /= events.Count;
+ // averagedNormal /= events.Count;
+ // CollisionEvent2D collision = new CollisionEvent2D();
+ // collision.Source = this.ParentObject;
+ // collision.Target = other.ParentObject;
+ // collision.LocalOffsetSrc = averagedLocalPoint;
+ // collision.Normal = Vector2.Normalize(averagedNormal);
+ // collision.Time = minTime;
+
+ // events.Clear();
+ // events.Add(collision);
+ // }
+ // return events;
+ //}
+
+ public List GetCornerPoints(float dt)
+ {
+ List cornerPoints = new List();
+ Vector2[] localPoints = new Vector2[4]
+ {
+ new Vector2(-_width / 2, -_height / 2),
+ new Vector2(_width / 2, -_height / 2),
+ new Vector2(_width / 2, _height / 2),
+ new Vector2(-_width / 2, _height / 2)
+ };
+ if (_bindObject.RigidBody != null)
+ {
+ var M = Matrix2x2.CreateRotationMatrix(_bindObject.OldRotation + _bindObject.RigidBody.AngularVelocity * dt);
+ for (int i = 0; i < 4; i++)
+ {
+
+ var curPos = _bindObject.OldPosition + _bindObject.RigidBody.LinearVelocity * dt
+ + M.Multiply(localPoints[i]);
+ cornerPoints.Add(curPos);
+ }
+ }
+ else
+ {
+ var M = Matrix2x2.CreateRotationMatrix(_bindObject.Rotation);
+ for (int i = 0; i < 4; i++)
+ {
+
+ var curPos = _bindObject.Position
+ + M.Multiply(localPoints[i]);
+ cornerPoints.Add(curPos);
+ }
+
+ }
+
+ return cornerPoints;
+ }
+
+ public override bool TestCollisionCondition(Collider2D other, float deltaTime, out CollisionInfo info)
+ {
+ info = new CollisionInfo();
+ if (other is BoxCollider)
+ {
+ BoxCollider b = (BoxCollider)other;
+ List edgesA = GetEdges(deltaTime);
+ List edgesB = b.GetEdges(deltaTime);
+ List cornersA = GetCornerPoints(deltaTime);
+ List cornersB = b.GetCornerPoints(deltaTime);
+ float depth;
+ Vector2 normal;
+ if (GeometryUtils.PolygonPolygonCollisionInfo(edgesA, cornersA, edgesB, cornersB, out depth, out normal))
+ {
+ info.Source = this.ParentObject;
+ info.Target = b.ParentObject;
+ info.Time = deltaTime;
+ info.Depth = depth;
+ info.Normal = Vector2.Dot(normal, ParentObject.RigidBody.CentroidWorldSpace - b.ParentObject.RigidBody.CentroidWorldSpace) < 0 ? -normal : normal;
+ return true;
+ }
+ }
+ else if (other is SphereCollider)
+ {
+ SphereCollider b = (SphereCollider)other;
+ float depth;
+ Vector2 normal;
+ bool collided = GeometryUtils.CirclePolygonCollisionInfo(b.ParentObject.Position, b.Radius, GetEdges(deltaTime),
+ GetCornerPoints(deltaTime),
+ out depth, out normal);
+ if (collided)
+ {
+ info.Source = this.ParentObject;
+ info.Target = b.ParentObject;
+ info.Time = deltaTime;
+ info.Depth = depth;
+ info.Normal = Vector2.Dot(normal, ParentObject.RigidBody.CentroidWorldSpace - b.ParentObject.RigidBody.CentroidWorldSpace) < 0 ? -normal : normal;
+ }
+ return collided;
+ }
+ else if (other is TileCollider)
+ {
+ float depth;
+ Vector2 normal;
+ if (TileCollisionUtils.GetPolygonTileCollisionInfo(GetAABB(deltaTime), ParentObject.RigidBody.CentroidWorldSpace,
+ GetEdges(deltaTime), GetCornerPoints(deltaTime), out depth, out normal))
+ {
+ info.Source = this.ParentObject;
+ info.Target = other.ParentObject;
+ info.Time = deltaTime;
+ info.Depth = depth;
+ info.Normal = Vector2.Dot(normal, ParentObject.RigidBody.CentroidWorldSpace - other.ParentObject.RigidBody.CentroidWorldSpace) < 0 ? -normal : normal;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override void GetContactInfo(in CollisionInfo info, float deltaTime,
+ out List collisionEvents)
+ {
+ collisionEvents = new List();
+ if (info.Target.Collider is BoxCollider)
+ {
+ BoxCollider b = (BoxCollider)info.Target.Collider;
+ List edgesA = GetEdges(deltaTime);
+ List edgesB = b.GetEdges(deltaTime);
+ List cornersA = GetCornerPoints(deltaTime);
+ List cornersB = b.GetCornerPoints(deltaTime);
+ var e = new CollisionEvent2D()
+ {
+ Time = info.Time,
+ Source = info.Source,
+ Target = info.Target,
+ LocalOffsetSrc = Vector2.Zero,
+ LocalOffsetTarget = Vector2.Zero,
+ Normal = info.Normal,
+ Position = Vector2.Zero,
+ Depth = info.Depth,
+ };
+ List> contacts = new List>();
+ GeometryUtils.PolygonPolygonContactInfo(edgesA, cornersA, edgesB, cornersB,
+ ParentObject.RigidBody.CentroidWorldSpace, b.ParentObject.RigidBody.CentroidWorldSpace,
+ contacts);
+ foreach (var c in contacts)
+ {
+ collisionEvents.Add(new CollisionEvent2D(e)
+ {
+ LocalOffsetSrc = c.Key,
+ LocalOffsetTarget = c.Value,
+ });
+ }
+ }
+ else if (info.Target.Collider is SphereCollider)
+ {
+ SphereCollider b = (SphereCollider)info.Target.Collider;
+ var e = new CollisionEvent2D()
+ {
+ Time = 0,
+ Source = info.Source,
+ Target = info.Target,
+ LocalOffsetSrc = Vector2.Zero,
+ LocalOffsetTarget = Vector2.Zero,
+ Normal = info.Normal,
+ Position = Vector2.Zero,
+ Depth = info.Depth,
+ };
+
+ List> contacts = new List>();
+ GeometryUtils.CirclePolygonContactInfo(b.ParentObject.RigidBody.CentroidWorldSpace, b.Radius, GetEdges(deltaTime),
+ GetCornerPoints(deltaTime), ParentObject.RigidBody.CentroidWorldSpace, contacts);
+ foreach (var c in contacts)
+ {
+ collisionEvents.Add(new CollisionEvent2D(e)
+ {
+ LocalOffsetSrc = c.Value,
+ LocalOffsetTarget = c.Key,
+ });
+ }
+
+ }
+ else if (info.Target.Collider is TileCollider)
+ {
+ TileCollisionUtils.GetPolygonTileContactInfo(GetAABB(deltaTime), ParentObject.RigidBody.CentroidWorldSpace,
+ GetEdges(deltaTime), GetCornerPoints(deltaTime), ParentObject, info.Target, deltaTime, collisionEvents);
+ }
+ }
+
+ public override AABB GetAABB(float deltaTime)
+ {
+ var points = GetCornerPoints(deltaTime);
+ Vector2 minPoint = points[0];
+ Vector2 maxPoint = points[0];
+ for (int i = 1; i < points.Count; i++)
+ {
+ minPoint.X = Math.Min(points[i].X, minPoint.X);
+ minPoint.Y = Math.Min(points[i].Y, minPoint.Y);
+ maxPoint.X = Math.Max(points[i].X, maxPoint.X);
+ maxPoint.Y = Math.Max(points[i].Y, maxPoint.Y);
+ }
+ return new AABB() { MaxPoint = maxPoint, MinPoint = minPoint };
+ }
+ }
+}
+
+
+//float maxDepth = -1;
+//if (edgeBelongsToA)
+//{
+// for (int i = 0; i < cornersB.Count; i++)
+// {
+// if (IsInsideEdge(cornersB[i], keyEdge))
+// {
+// float d = Utils.PointDistance2ToSegment(cornersB[i], keyEdge._pA, keyEdge._pB);
+// if (d > maxDepth)
+// {
+// maxDepth = d;
+// }
+// }
+// }
+// Debug.Assert(maxDepth >= 0);
+// for (int i = 0; i < cornersB.Count; i++)
+// {
+// if (IsInsideEdge(cornersB[i], keyEdge))
+// {
+// float d = Utils.PointDistance2ToSegment(cornersB[i], keyEdge._pA, keyEdge._pB);
+// if (d == maxDepth)
+// {
+// collisionEvents.Add(new CollisionEvent2D()
+// {
+// Time = 0,
+// Source = this.ParentObject,
+// Target = b.ParentObject,
+// LocalOffsetSrc = Utils.ProjectPointOnSegment(cornersB[i], keyEdge._pA, keyEdge._pB)
+// - ParentObject.RigidBody.CentroidWorldSpace,
+// LocalOffsetTarget = cornersB[i] - b.ParentObject.RigidBody.CentroidWorldSpace,
+// Normal = normal,
+// Position = Vector2.Zero,
+// Depth = depth
+// });
+// }
+// }
+// }
+
+//}
+//else
+//{
+// for (int i = 0; i < cornersA.Count; i++)
+// {
+// if (IsInsideEdge(cornersA[i], keyEdge))
+// {
+// float d = Utils.PointDistance2ToSegment(cornersA[i], keyEdge._pA, keyEdge._pB);
+// if (d > maxDepth)
+// {
+// maxDepth = d;
+// }
+// }
+// }
+// Debug.Assert(maxDepth >= 0);
+// for (int i = 0; i < cornersA.Count; i++)
+// {
+// if (IsInsideEdge(cornersA[i], keyEdge))
+// {
+// float d = Utils.PointDistance2ToSegment(cornersA[i], keyEdge._pA, keyEdge._pB);
+// if (d == maxDepth)
+// {
+// collisionEvents.Add(new CollisionEvent2D()
+// {
+// Time = 0,
+// Source = b.ParentObject,
+// Target = this.ParentObject,
+// LocalOffsetSrc = Utils.ProjectPointOnSegment(cornersA[i], keyEdge._pA, keyEdge._pB)
+// - b.ParentObject.RigidBody.CentroidWorldSpace,
+// LocalOffsetTarget = cornersA[i] - ParentObject.RigidBody.CentroidWorldSpace,
+// Normal = -normal,
+// Position = Vector2.Zero,
+// Depth = depth
+// });
+// }
+// }
+// }
+//}
+//collisionEvents.Add(new CollisionEvent2D()
+//{
+// Time = 0,
+// Source = this.ParentObject,
+// Target = b.ParentObject,
+// LocalOffsetSrc = curPoint - (b.ParentObject.RigidBody.CentroidWorldSpace + b.ParentObject.RigidBody.LinearVelocity * (float)ans),
+// LocalOffsetTarget = curPoint - (ParentObject.RigidBody.CentroidWorldSpace + ParentObject.RigidBody.LinearVelocity * (float)ans),
+// Normal = -Vector2.Normalize(Utils.Rotate90(closestEdge._pB - closestEdge._pA)),
+// Position = curPoint,
+//});
+
+//AABBCollider b = (AABBCollider)other;
+//double l = 0, r = deltaTime;
+//double ans = r;
+//while (r - l > deltaTime * 1e-2)
+//{
+// double midTime = (r + l) / 2.0;
+// if (IsCollideWith(b, (float)midTime))
+// {
+// ans = Math.Min(ans, midTime);
+// r = midTime;
+// }
+// else
+// {
+// l = midTime;
+// }
+//}
+
+//double t = Math.Max(0, ans);
+//var curPointsA = GetCornerPoints((float)ans);
+//var curEdgesA = GetEdges((float)ans);
+//var curPointsB = b.GetCornerPoints((float)ans);
+//var curEdgesB = b.GetEdges((float)ans);
+
+//// Vertex/Edge collision, A to B
+//foreach (var curPoint in curPointsA)
+//{
+// bool isInside = true;
+// Edge2D closestEdge = null;
+// float closestDistance = float.PositiveInfinity;
+// foreach(var curEdge in curEdgesB)
+// {
+// if (!IsInsideEdge(curPoint, curEdge))
+// {
+// isInside = false;
+// break;
+// }
+// float dist = Utils.PointDistance2ToSegment(curPoint, curEdge._pA, curEdge._pB);
+// if (dist < closestDistance)
+// {
+// closestDistance = dist;
+// closestEdge = curEdge;
+// }
+// }
+
+// if(isInside)
+// {
+// collisionEvents.Add(new CollisionEvent2D()
+// {
+// Time = (float)(t),
+// Source = this.ParentObject,
+// Target = b.ParentObject,
+// LocalOffsetSrc = curPoint - (ParentObject.RigidBody.CentroidWorldSpace + ParentObject.RigidBody.LinearVelocity * (float)ans),
+// LocalOffsetTarget = curPoint - (b.ParentObject.RigidBody.CentroidWorldSpace + b.ParentObject.RigidBody.LinearVelocity * (float)ans),
+// Normal = -Vector2.Normalize(Utils.Rotate90(closestEdge._pB - closestEdge._pA)),
+// Position = curPoint,
+
+// });
+// }
+
+//}
+
+//// Vertex/Edge collision, B to A
+//foreach (var curPoint in curPointsB)
+//{
+// bool isInside = true;
+// Edge2D closestEdge = null;
+// float closestDistance = float.PositiveInfinity;
+// foreach (var curEdge in curEdgesA)
+// {
+// if (!IsInsideEdge(curPoint, curEdge))
+// {
+// isInside = false;
+// break;
+// }
+// float dist = Utils.PointDistance2ToSegment(curPoint, curEdge._pA, curEdge._pB);
+// if (dist < closestDistance)
+// {
+// closestDistance = dist;
+// closestEdge = curEdge;
+// }
+// }
+
+// if (isInside)
+// {
+// collisionEvents.Add(new CollisionEvent2D()
+// {
+// Time = (float)(t),
+// Source = b.ParentObject,
+// Target = this.ParentObject,
+// LocalOffsetSrc = curPoint - (b.ParentObject.RigidBody.CentroidWorldSpace + b.ParentObject.RigidBody.LinearVelocity * (float)ans),
+// LocalOffsetTarget = curPoint - (ParentObject.RigidBody.CentroidWorldSpace + ParentObject.RigidBody.LinearVelocity * (float)ans),
+// Normal = -Vector2.Normalize(Utils.Rotate90(closestEdge._pB - closestEdge._pA)),
+// Position = curPoint,
+// });
+// }
+
+//}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/Collider2D.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/Collider2D.cs
new file mode 100644
index 000000000..c3c3381de
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/Collider2D.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.Colliders
+{
+ ///
+ /// 碰撞组件的基类
+ ///
+ public abstract class Collider2D
+ {
+ public PhysicsObject ParentObject
+ {
+ get => _bindObject;
+ set => _bindObject = value;
+ }
+
+ protected PhysicsObject _bindObject;
+ public abstract double InertiaTensor(float mass);
+ public abstract List GetWireFrameWires();
+ // public abstract List GetCollisionEvents(Collider2D other, float deltaTime);
+
+ public abstract bool TestCollisionCondition(Collider2D other, float deltaTime, out CollisionInfo info);
+
+ public abstract void GetContactInfo(in CollisionInfo info, float deltaTime,
+ out List collisionEvents);
+
+ //public abstract List GetContactInfo(CollisionEvent2D e, float deltaTime);
+
+ public abstract AABB GetAABB(float deltaTime);
+ public Collider2D()
+ {
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/SphereCollider.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/SphereCollider.cs
new file mode 100644
index 000000000..d60629b3a
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/SphereCollider.cs
@@ -0,0 +1,201 @@
+using Everglow.Commons.Physics.PBEngine.GameInteraction;
+using Everglow.Commons.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.Colliders
+{
+ ///
+ /// 圆形碰撞体
+ ///
+ public class SphereCollider : Collider2D
+ {
+ public float Radius
+ {
+ get => _radius; set => _radius = value;
+ }
+ private float _radius;
+ public SphereCollider(float radius)
+ {
+ _radius = radius;
+ }
+ public override AABB GetAABB(float deltaTime)
+ {
+ var center = ParentObject.OldPosition + ParentObject.RigidBody.LinearVelocity * deltaTime;
+ return new AABB() {
+ MinPoint = center - new Vector2(_radius, _radius),
+ MaxPoint = center + new Vector2(_radius, _radius),
+ };
+ }
+
+ public override void GetContactInfo(in CollisionInfo info, float deltaTime, out List collisionEvents)
+ {
+ collisionEvents = new List();
+ if (info.Target.Collider is SphereCollider)
+ {
+ SphereCollider b = (SphereCollider)info.Target.Collider;
+ var e = new CollisionEvent2D()
+ {
+ Time = info.Time,
+ Source = this.ParentObject,
+ Target = b.ParentObject,
+ LocalOffsetSrc = Vector2.Zero,
+ LocalOffsetTarget = Vector2.Zero,
+ Normal = info.Normal,
+ Position = Vector2.Zero,
+ Depth = info.Depth,
+ };
+
+ var unit = (ParentObject.RigidBody.CentroidWorldSpace - b.ParentObject.RigidBody.CentroidWorldSpace).SafeNormalize(Vector2.Zero);
+ collisionEvents.Add(new CollisionEvent2D(e)
+ {
+ LocalOffsetSrc = -unit * _radius,
+ LocalOffsetTarget = unit * b.Radius,
+ });
+ }
+ else if (info.Target.Collider is BoxCollider)
+ {
+ BoxCollider b = (BoxCollider)info.Target.Collider;
+ var e = new CollisionEvent2D()
+ {
+ Time = info.Time,
+ Source = info.Source,
+ Target = info.Target,
+ LocalOffsetSrc = Vector2.Zero,
+ LocalOffsetTarget = Vector2.Zero,
+ Normal = Vector2.Dot(info.Normal, ParentObject.RigidBody.CentroidWorldSpace - b.ParentObject.RigidBody.CentroidWorldSpace) < 0 ? -info.Normal : info.Normal,
+ Position = Vector2.Zero,
+ Depth = info.Depth,
+ };
+
+ List> contacts = new List>();
+ GeometryUtils.CirclePolygonContactInfo(ParentObject.RigidBody.CentroidWorldSpace, _radius, b.GetEdges(deltaTime),
+ b.GetCornerPoints(deltaTime), b.ParentObject.RigidBody.CentroidWorldSpace, contacts);
+ foreach (var c in contacts)
+ {
+ collisionEvents.Add(new CollisionEvent2D(e)
+ {
+ LocalOffsetSrc = c.Key,
+ LocalOffsetTarget = c.Value,
+ });
+ }
+ }
+ else if (info.Target.Collider is TileCollider)
+ {
+ TileCollisionUtils.GetSphereTileContactInfo(ParentObject.RigidBody.CentroidWorldSpace, _radius,
+ ParentObject, info.Target, deltaTime, collisionEvents);
+ }
+ }
+
+ //public override List GetContactInfo(CollisionEvent2D e, float deltaTime)
+ //{
+ // List events = new List();
+ // if (e.Target.Collider is SphereCollider)
+ // {
+ // SphereCollider b = (SphereCollider)e.Target.Collider;
+ // var unit = (ParentObject.RigidBody.CentroidWorldSpace - b.ParentObject.RigidBody.CentroidWorldSpace).SafeNormalize(Vector2.Zero);
+ // events.Add(new CollisionEvent2D(e)
+ // {
+ // LocalOffsetSrc = -unit * _radius,
+ // LocalOffsetTarget = unit * b.Radius,
+ // });
+ // }
+ // else if (e.Target.Collider is BoxCollider)
+ // {
+ // BoxCollider b = (BoxCollider)e.Target.Collider;
+ // List edgesB = b.GetEdges(deltaTime);
+ // List cornersB = b.GetCornerPoints(deltaTime);
+ // List> contacts = new List>();
+ // Utils.CirclePolygonContactInfo(ParentObject.RigidBody.CentroidWorldSpace, _radius, edgesB,
+ // cornersB, b.ParentObject.RigidBody.CentroidWorldSpace, contacts);
+ // foreach (var c in contacts)
+ // {
+ // events.Add(new CollisionEvent2D(e)
+ // {
+ // LocalOffsetSrc = c.Key,
+ // LocalOffsetTarget = c.Value,
+ // });
+ // }
+ // }
+ // else if (e.Target.Collider is TileCollider)
+ // {
+ // TileCollisionUtils.GetSphereTileContactInfo(ParentObject.RigidBody.CentroidWorldSpace, _radius, e, events);
+ // }
+ // return events;
+ //}
+
+ public override List GetWireFrameWires()
+ {
+ List lines = new List();
+ float da = MathHelper.TwoPi / 64;
+ for (int i = 0; i < 64; i++)
+ {
+ lines.Add((i * da).ToRotationVector2() * _radius);
+ lines.Add(((i + 1) * da).ToRotationVector2() * _radius);
+ }
+ lines.Add(Vector2.Zero);
+ lines.Add(Matrix2x2.CreateRotationMatrix(ParentObject.Rotation).Multiply(new Vector2(_radius, 0)));
+ return lines;
+ }
+
+ public override double InertiaTensor(float mass)
+ {
+ return 0.5 * mass * _radius * _radius;
+ }
+
+ public override bool TestCollisionCondition(Collider2D other, float deltaTime, out CollisionInfo info)
+ {
+ info = new CollisionInfo();
+ if (other is SphereCollider)
+ {
+ SphereCollider b = (SphereCollider)other;
+ float d = Vector2.DistanceSquared(ParentObject.RigidBody.CentroidWorldSpace, b.ParentObject.RigidBody.CentroidWorldSpace);
+ if (d < (_radius + b._radius) * (_radius + b._radius))
+ {
+ info.Source = this.ParentObject;
+ info.Target = b.ParentObject;
+ info.Time = deltaTime;
+ info.Depth = _radius + b._radius - (float)Math.Sqrt(d);
+ info.Normal = (ParentObject.RigidBody.CentroidWorldSpace - b.ParentObject.RigidBody.CentroidWorldSpace).SafeNormalize(Vector2.One);
+ return true;
+ }
+ }
+ else if (other is BoxCollider)
+ {
+ BoxCollider b = (BoxCollider)other;
+ float depth;
+ Vector2 normal;
+ if (GeometryUtils.CirclePolygonCollisionInfo(ParentObject.RigidBody.CentroidWorldSpace, _radius,
+ b.GetEdges(deltaTime), b.GetCornerPoints(deltaTime), out depth, out normal))
+ {
+ info.Source = this.ParentObject;
+ info.Target = b.ParentObject;
+ info.Time = deltaTime;
+ info.Depth = depth;
+ info.Normal = Vector2.Dot(normal, ParentObject.RigidBody.CentroidWorldSpace - b.ParentObject.RigidBody.CentroidWorldSpace) < 0 ? -normal : normal;
+ return true;
+ }
+ }
+ else if (other is TileCollider)
+ {
+ float depth;
+ Vector2 normal;
+ if (TileCollisionUtils.GetSphereTileCollisionInfo(ParentObject.RigidBody.CentroidWorldSpace, _radius,
+ ParentObject, info.Target, out depth, out normal))
+ {
+ info.Source = this.ParentObject;
+ info.Target = other.ParentObject;
+ info.Time = deltaTime;
+ info.Depth = depth;
+ info.Normal = normal;
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionEvent2D.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionEvent2D.cs
new file mode 100644
index 000000000..1bf3abbaf
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionEvent2D.cs
@@ -0,0 +1,65 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision
+{
+ ///
+ /// 储存碰撞事件的对象,包括接触点信息
+ ///
+ public class CollisionEvent2D
+ {
+ public PhysicsObject Source;
+ public PhysicsObject Target;
+ public float Time;
+ public float Depth;
+ public Vector2 Position;
+ public Vector2 Normal;
+ public Vector2 Offset;
+
+ ///
+ /// From centroid of source object to hit point
+ ///
+ public Vector2 LocalOffsetSrc;
+
+ ///
+ /// From centroid of target object to hit point
+ ///
+ public Vector2 LocalOffsetTarget;
+ public float NormalVelOld;
+
+ public CollisionEvent2D(CollisionEvent2D e)
+ {
+ this.Source = e.Source;
+ this.Target = e.Target;
+ this.Time = e.Time;
+ this.Depth = e.Depth;
+ this.Position = e.Position;
+ this.Normal = e.Normal;
+ this.Offset = e.Offset;
+ this.NormalVelOld = e.NormalVelOld;
+ }
+
+ public CollisionEvent2D()
+ {
+ }
+
+ public CollisionEvent2D CreateMirrorEvent()
+ {
+ return new CollisionEvent2D()
+ {
+ Source = this.Target,
+ Target = this.Source,
+ Time = this.Time,
+ Position = this.Position,
+ Normal = -this.Normal,
+ Offset = -this.Offset,
+ LocalOffsetSrc = this.LocalOffsetTarget,
+ LocalOffsetTarget = this.LocalOffsetSrc
+ };
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionInfo.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionInfo.cs
new file mode 100644
index 000000000..2cbe19e95
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/CollisionInfo.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision
+{
+ ///
+ /// 储存碰撞事件的对象,包括穿透深度和挤出方向,不包括接触点
+ ///
+ public struct CollisionInfo
+ {
+ public PhysicsObject Source;
+ public PhysicsObject Target;
+ public float Time;
+ public float Depth;
+ public Vector2 Normal;
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/Edge2D.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/Edge2D.cs
new file mode 100644
index 000000000..bf0824a82
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/Edge2D.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Everglow.Commons.Utilities;
+using Terraria;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision
+{
+ public class Edge2D
+ {
+ public Vector2 _pA, _pB;
+ public Edge2D()
+ {
+
+ }
+
+ public Edge2D(Vector2 A, Vector2 B)
+ {
+ _pA = A;
+ _pB = B;
+ }
+
+ public Vector2 GetNormal()
+ {
+ return -GeometryUtils.Rotate90((_pB - _pA).SafeNormalize(Vector2.Zero));
+ }
+
+ public bool Segment_Segment_Collision(Vector2 a, Vector2 b, out CollisionEvent2D collisionEvent)
+ {
+ Matrix2x2 M = new Matrix2x2
+ {
+ [0, 0] = _pB.X - _pA.X,
+ [0, 1] = -(b.X - a.X),
+ [1, 0] = _pB.Y - _pA.Y,
+ [1, 1] = -(b.Y - a.Y),
+ };
+
+ double det = M.Determinant();
+ if (Math.Abs(det) < 1e-7)
+ {
+ collisionEvent = new CollisionEvent2D();
+ return false; // parallel lines
+ }
+ else
+ {
+
+ Vector2 st = M.Adjoint().Multiply(a - _pA) / (float)det;
+ if (st.X >= 0 && st.X <= 1.0f && st.Y >= 0 && st.Y <= 1.0f)
+ {
+ collisionEvent = new CollisionEvent2D
+ {
+ Time = st.Y,
+ Position = _pA + (_pB - _pA) * st.X,
+ Normal = -GeometryUtils.Rotate90((_pB - _pA).SafeNormalize(Vector2.Zero)),
+ Offset = Vector2.Zero
+ };
+ return true;
+ }
+ collisionEvent = new CollisionEvent2D();
+ return false; // intersection is outside of the line segments
+ }
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/ImpluseEntry.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/ImpluseEntry.cs
new file mode 100644
index 000000000..8c9449e0c
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/ImpluseEntry.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision
+{
+ public struct ImpluseEntry
+ {
+ public RigidBody2D Source;
+ public RigidBody2D Target;
+ public Vector2 ImpluseSource;
+ public Vector2 RelativePositionSource;
+ public Vector2 ImpluseTarget;
+ public Vector2 RelativePositionTarget;
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/MovementType.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/MovementType.cs
new file mode 100644
index 000000000..fcb1f8c5e
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/MovementType.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision
+{
+ ///
+ /// 刚体的移动模式,用于区分模拟方法以及提升性能
+ ///
+ public enum MovementType
+ {
+ ///
+ /// 静态物体,无法移动、转向
+ ///
+ Static,
+ ///
+ /// 动态物体,但是拥有无限质量,动作无法被其他动态物体影响
+ ///
+ Kinematic,
+ ///
+ /// 玩家物体,动态,具有质量但是不可旋转
+ ///
+ Player,
+ ///
+ /// 动态物体,可以任意移动和旋转,可以被任何物体影响
+ ///
+ Dynamic
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Constrains/Constrain.cs b/Sources/Everglow.Core/Physics/PBEngine/Constrains/Constrain.cs
new file mode 100644
index 000000000..3ec8fbbc5
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Constrains/Constrain.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.Constrains
+{
+ public abstract class Constrain
+ {
+ public abstract void Apply(float deltaTime);
+
+ public abstract List GetDrawMesh();
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Constrains/JointConstrain.cs b/Sources/Everglow.Core/Physics/PBEngine/Constrains/JointConstrain.cs
new file mode 100644
index 000000000..7c1a8283d
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Constrains/JointConstrain.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria;
+
+namespace Everglow.Commons.Physics.PBEngine.Constrains
+{
+ ///
+ /// TODO: 待定约束
+ ///
+ public class JointConstrain : Constrain
+ {
+ private PhysicsObject _objA;
+ private PhysicsObject _objB;
+ private Vector2 _localPosA;
+ private Vector2 _localPosB;
+ public JointConstrain(PhysicsObject A, PhysicsObject B, Vector2 localPos1, Vector2 localPos2)
+ {
+ _objA = A;
+ _objB = B;
+ _localPosA = localPos1;
+ _localPosB = localPos2;
+ }
+
+ public override void Apply(float deltaTime)
+ {
+ var pA = _objA.LocalToWorldPos(_localPosA);
+ // var pB = _objB.LocalToWorldPos(_localPosB);
+ float w = _objA.RigidBody.InvMass + _objB.RigidBody.InvMass;
+ float weightA = _objA.RigidBody.InvMass / w;
+ var newCenter = pA;
+ var dirA = (newCenter - _objA.Position).SafeNormalize(Vector2.One);
+ var dirB = (newCenter - _objB.Position).SafeNormalize(Vector2.One);
+
+ float oldRotA = MathHelper.WrapAngle(_objA.Rotation);
+ float oldRotB = MathHelper.WrapAngle(_objB.Rotation);
+ //_objA.Rotation = (float)(Math.Atan2(dirA.Y, dirA.X) - Math.Atan2(_localPosA.Y, _localPosA.X));
+ //_objB.Rotation = (float)(Math.Atan2(dirB.Y, dirB.X) - Math.Atan2(_localPosB.Y, _localPosB.X));
+
+ Vector2 addA = newCenter - _objA.LocalToWorldPos(_localPosA);
+ Vector2 addB = newCenter - _objB.LocalToWorldPos(_localPosB);
+ Vector2 oldPosB = _objB.Position;
+ _objA.Position += addA;
+ _objB.Position = (newCenter - dirB * 200);
+
+ _objA.RigidBody.LinearVelocity = (_objA.Position - _objA.OldPosition) / deltaTime;
+ _objB.RigidBody.LinearVelocity = (_objB.Position - _objB.OldPosition) / deltaTime;
+ //_objA.RigidBody.AngularVelocity = MathHelper.WrapAngle(_objA.Rotation - _objA.OldRotation) / deltaTime;
+ //_objB.RigidBody.AngularVelocity = MathHelper.WrapAngle(_objB.Rotation - _objB.OldRotation) / deltaTime;
+ }
+
+ public override List GetDrawMesh()
+ {
+ List drawMesh = new List();
+ drawMesh.Add(_objA.LocalToWorldPos(_localPosA));
+ drawMesh.Add(_objB.RigidBody.CentroidWorldSpace);
+
+ return drawMesh;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs b/Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs
new file mode 100644
index 000000000..ed2447b90
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Everglow.Commons.Utilities;
+using Terraria;
+
+namespace Everglow.Commons.Physics.PBEngine.Constrains
+{
+ ///
+ /// 弹簧约束
+ ///
+ public class SpringConstrain : Constrain
+ {
+ private PhysicsObject _objA;
+ private PhysicsObject _objB;
+ private float _compliance;
+ private float _restLength;
+ private float _lambda;
+ private Vector2 _localPosA;
+ private Vector2 _localPosB;
+
+ public SpringConstrain(PhysicsObject A, PhysicsObject B, float elasticity, float restLength)
+ {
+ _objA = A;
+ _objB = B;
+ _compliance = 1 / elasticity;
+ _restLength = restLength;
+ _lambda = 0;
+ _localPosA = Vector2.Zero;
+ _localPosB = Vector2.Zero;
+ }
+
+ public SpringConstrain(PhysicsObject A, PhysicsObject B, float elasticity, float restLength,
+ Vector2 localPosA,
+ Vector2 localPosB) : this(A, B, elasticity, restLength)
+ {
+ _localPosA = localPosA;
+ _localPosB = localPosB;
+ }
+
+ public override void Apply(float deltaTime)
+ {
+ var pA = _objA.LocalToWorldPos(_localPosA);
+ var pB = _objB.LocalToWorldPos(_localPosB);
+ var L = (pB - pA).Length();
+ var unit = (pB - pA).SafeNormalize(Vector2.Zero);
+ float C = L - _restLength;
+ float alpha = _compliance / deltaTime / deltaTime;
+ float d_lambda = (-C - alpha * _lambda) / (_objA.RigidBody.InvMass + _objB.RigidBody.InvMass + alpha);
+
+ _lambda += d_lambda;
+ var curPosA = pA + _lambda * _objA.RigidBody.InvMass * -unit;
+ var curPosB = pB + _lambda * _objB.RigidBody.InvMass * unit;
+
+ var ra = Matrix2x2.CreateRotationMatrix(_objA.Rotation).Multiply(_localPosA);
+ var rb = Matrix2x2.CreateRotationMatrix(_objB.Rotation).Multiply(_localPosB);
+ var da = (_lambda * _objA.RigidBody.InvMass * -unit).SafeNormalize(Vector2.Zero);
+ var db = (_lambda * _objB.RigidBody.InvMass * unit).SafeNormalize(Vector2.Zero);
+ var oldVelA = Vector2.Dot(_objA.RigidBody.LinearVelocity + GeometryUtils.AnuglarVelocityToLinearVelocity(ra, _objA.RigidBody.AngularVelocity), da);
+ var oldVelB = Vector2.Dot(_objB.RigidBody.LinearVelocity + GeometryUtils.AnuglarVelocityToLinearVelocity(rb, _objB.RigidBody.AngularVelocity), db);
+
+ double rAdotN = Vector2.Dot(GeometryUtils.Rotate90(ra), da);
+ double rBdotN = Vector2.Dot(GeometryUtils.Rotate90(rb), db);
+ double R1 = rAdotN * rAdotN * _objA.RigidBody.GlobalInverseInertiaTensor;
+ double R2 = rBdotN * rBdotN * _objB.RigidBody.GlobalInverseInertiaTensor;
+ var impluseA = ((curPosA - pA).Length() / deltaTime - oldVelA) / (_objA.RigidBody.InvMass + (float)R1);
+ var impluseB = ((curPosB - pB).Length() / deltaTime - oldVelB) / (_objB.RigidBody.InvMass + (float)R2);
+
+ if (_objA.RigidBody.InvMass != 0)
+ {
+ _objA.RigidBody.AddImpluseImmediate(impluseA * da, ra);
+ _objA.Position += _objA.RigidBody.LinearVelocity * deltaTime;
+ _objA.Rotation += _objA.RigidBody.AngularVelocity * deltaTime;
+ }
+ if (_objB.RigidBody.InvMass != 0)
+ {
+ _objB.RigidBody.AddImpluseImmediate(impluseB * db, rb);
+ _objB.Position += _objB.RigidBody.LinearVelocity * deltaTime;
+ _objB.Rotation += _objB.RigidBody.AngularVelocity * deltaTime;
+ }
+ //_objA.RigidBody.AngularVelocity = Utils.Cross(_localPosA, _objA.RigidBody.LinearVelocity);
+ //_objB.RigidBody.AngularVelocity = Utils.Cross(_localPosB, _objB.RigidBody.LinearVelocity);
+ }
+
+ public override List GetDrawMesh()
+ {
+ List drawMesh = new List();
+ drawMesh.Add(_objA.LocalToWorldPos(_localPosA));
+ drawMesh.Add(_objB.LocalToWorldPos(_localPosB));
+
+ return drawMesh;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollider.cs b/Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollider.cs
new file mode 100644
index 000000000..2cf5b8b38
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollider.cs
@@ -0,0 +1,55 @@
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.GameInteraction
+{
+ ///
+ /// 与TR世界地形碰撞的碰撞体
+ ///
+ public class TileCollider : Collider2D
+ {
+ public override AABB GetAABB(float deltaTime)
+ {
+ return new AABB()
+ {
+ MinPoint = new Vector2(float.NegativeInfinity, float.NegativeInfinity),
+ MaxPoint = new Vector2(float.PositiveInfinity, 0)
+ };
+ }
+
+ public override void GetContactInfo(in CollisionInfo info, float deltaTime, out List collisionEvents)
+ {
+ // Leave empty since static object will not serve as collision source
+
+ collisionEvents = new List();
+ }
+
+ //public override List GetContactInfo(CollisionEvent2D e, float deltaTime)
+ //{
+ // return new List();
+ // // Leave empty since static object will not serve as collision source
+ //}
+
+ public override List GetWireFrameWires()
+ {
+ return new List();
+ }
+
+ public override double InertiaTensor(float mass)
+ {
+ return 1;
+ }
+
+ public override bool TestCollisionCondition(Collider2D other, float deltaTime, out CollisionInfo info)
+ {
+ // Leave empty since static object will not serve as collision source
+ info = new CollisionInfo();
+ return false;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollisionUtils.cs b/Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollisionUtils.cs
new file mode 100644
index 000000000..c521d1859
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/GameInteraction/TileCollisionUtils.cs
@@ -0,0 +1,300 @@
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria;
+using static Humanizer.In;
+
+namespace Everglow.Commons.Physics.PBEngine.GameInteraction
+{
+ ///
+ /// 与TR地形进行碰撞检测的函数
+ ///
+ public class TileCollisionUtils
+ {
+ public static List GenerateHalfBrick(int x, int y)
+ {
+ var slope = Main.tile[x, y].Slope;
+ if (slope == Terraria.ID.SlopeType.Solid)
+ {
+ if (Main.tile[x, y].IsHalfBlock)
+ {
+ return new List()
+ {
+ new Vector2(x * 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 - 8 ),
+ new Vector2(x * 16, -y * 16 - 8)
+ };
+ }
+ else
+ {
+ return new List()
+ {
+ new Vector2(x * 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 ),
+ new Vector2(x * 16, -y * 16)
+ };
+ }
+ }
+ else if (slope == Terraria.ID.SlopeType.SlopeDownLeft)
+ {
+ return new List()
+ {
+ new Vector2(x * 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 - 16),
+ new Vector2(x * 16, -y * 16)
+ };
+ }
+ else if (slope == Terraria.ID.SlopeType.SlopeDownRight)
+ {
+ return new List()
+ {
+ new Vector2(x * 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 )
+ };
+ }
+ else if (slope == Terraria.ID.SlopeType.SlopeUpLeft)
+ {
+ return new List()
+ {
+ new Vector2(x * 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 ),
+ new Vector2(x * 16, -y * 16)
+ };
+ }
+ else if (slope == Terraria.ID.SlopeType.SlopeUpRight)
+ {
+ return new List()
+ {
+ new Vector2(x * 16 + 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 ),
+ new Vector2(x * 16, -y * 16)
+ };
+ }
+ return new List()
+ {
+ new Vector2(x * 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 - 16),
+ new Vector2(x * 16 + 16, -y * 16 ),
+ new Vector2(x * 16, -y * 16)
+ };
+ }
+
+ public static bool GetPolygonTileCollisionInfo(AABB boundingBox, Vector2 polyCenter, List edges, List corners,
+ out float depth1, out Vector2 normal1)
+ {
+ bool collided = false;
+ float maxDepth = 0;
+ Vector2 maxNormal = Vector2.Zero;
+ int minX = (int)Math.Floor((boundingBox.MinPoint.X) / 16);
+ int maxX = (int)Math.Ceiling((boundingBox.MaxPoint.X) / 16);
+ int minY = (int)Math.Floor((-boundingBox.MaxPoint.Y) / 16);
+ int maxY = (int)Math.Ceiling((-boundingBox.MinPoint.Y) / 16);
+
+ for (int x = Math.Max(minX, 0); x <= Math.Min(maxX, Main.maxTilesX - 1); x++)
+ {
+ for (int y = Math.Max(minY, 0); y <= Math.Min(maxY, Main.maxTilesY - 1); y++)
+ {
+ if (Main.tile[x, y] != null && Main.tile[x, y].HasTile && Main.tileSolid[Main.tile[x, y].TileType])
+ {
+ var localPoints = GenerateHalfBrick(x, y);
+ List edgesTile = new List();
+ for (int i = 0; i < localPoints.Count; i++)
+ {
+ edgesTile.Add(new Edge2D(localPoints[i], localPoints[(i + 1) % localPoints.Count]));
+ }
+ var centerTile = new Vector2(x * 16 + 8, -y * 16 - 8);
+ float depth;
+ Vector2 normal;
+ if (GeometryUtils.PolygonPolygonCollisionInfo(edges, corners, edgesTile, localPoints,
+ out depth, out normal))
+ {
+ collided = true;
+
+ if (depth > maxDepth)
+ {
+ maxDepth = depth;
+ maxNormal = Vector2.Dot(maxNormal, polyCenter - centerTile) < 0 ? -normal : normal;
+ }
+ }
+ }
+ }
+ }
+ depth1 = 0;
+ normal1 = maxNormal;
+ return collided;
+ }
+ public static void GetPolygonTileContactInfo(AABB boundingBox, Vector2 polyCenter, List edges,
+ List corners,
+ PhysicsObject A, PhysicsObject B,
+ float deltaTime,
+ List outputList)
+ {
+
+ Vector2 maxNormal = Vector2.Zero;
+ int minX = (int)Math.Floor((boundingBox.MinPoint.X) / 16);
+ int maxX = (int)Math.Ceiling((boundingBox.MaxPoint.X) / 16);
+ int minY = (int)Math.Floor((-boundingBox.MaxPoint.Y) / 16);
+ int maxY = (int)Math.Ceiling((-boundingBox.MinPoint.Y) / 16);
+
+ for (int x = Math.Max(minX, 0); x <= Math.Min(maxX, Main.maxTilesX - 1); x++)
+ {
+ for (int y = Math.Max(minY, 0); y <= Math.Min(maxY, Main.maxTilesY - 1); y++)
+ {
+ if (Main.tile[x, y] != null && Main.tile[x, y].HasTile && Main.tileSolid[Main.tile[x, y].TileType])
+ {
+ var localPoints = GenerateHalfBrick(x, y);
+ List edgesTile = new List();
+ for (int i = 0; i < localPoints.Count; i++)
+ {
+ edgesTile.Add(new Edge2D(localPoints[i], localPoints[(i + 1) % localPoints.Count]));
+ }
+ var centerTile = new Vector2(x * 16 + 8, -y * 16 - 8);
+ float depth;
+ Vector2 normal;
+ if (GeometryUtils.PolygonPolygonCollisionInfo(edges, corners, edgesTile, localPoints,
+ out depth, out normal))
+ {
+ var e = new CollisionEvent2D()
+ {
+ Time = 0,
+ Source = A,
+ Target = B,
+ LocalOffsetSrc = Vector2.Zero,
+ LocalOffsetTarget = Vector2.Zero,
+ Normal = Vector2.Dot(normal, polyCenter - centerTile) < 0 ? -normal : normal,
+ Position = Vector2.Zero,
+ Depth = depth,
+ };
+ float weightA = e.Source.RigidBody.InvMass / (e.Source.RigidBody.InvMass + e.Target.RigidBody.InvMass);
+ float weightB = e.Target.RigidBody.InvMass / (e.Source.RigidBody.InvMass + e.Target.RigidBody.InvMass);
+ e.Source.RigidBody.MoveBody(e.Normal * weightA * e.Depth, deltaTime);
+ e.Target.RigidBody.MoveBody(-e.Normal * weightB * e.Depth, deltaTime);
+
+ List> contacts = new List>();
+ GeometryUtils.PolygonPolygonContactInfo(edges, corners, edgesTile, localPoints.ToList(), polyCenter,
+ centerTile, contacts);
+ foreach (var c in contacts)
+ {
+ outputList.Add(new CollisionEvent2D(e)
+ {
+ LocalOffsetSrc = c.Key,
+ LocalOffsetTarget = c.Value,
+ });
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static bool GetSphereTileCollisionInfo(Vector2 center, float radius, PhysicsObject A, PhysicsObject B,
+ out float depth1, out Vector2 normal1)
+ {
+ bool collided = false;
+ float maxDepth = 0;
+ Vector2 maxNormal = Vector2.Zero;
+ int minX = (int)Math.Floor((center.X - radius) / 16);
+ int maxX = (int)Math.Ceiling((center.X + radius) / 16);
+ int minY = (int)Math.Floor((-center.Y - radius) / 16);
+ int maxY = (int)Math.Ceiling((-center.Y + radius) / 16);
+
+ for (int x = Math.Max(minX, 0); x <= Math.Min(maxX, Main.maxTilesX - 1); x++)
+ {
+ for (int y = Math.Max(minY, 0); y <= Math.Min(maxY, Main.maxTilesY - 1); y++)
+ {
+ if (Main.tile[x, y] != null && Main.tile[x, y].HasTile && Main.tileSolid[Main.tile[x, y].TileType])
+ {
+ var localPoints = GenerateHalfBrick(x, y);
+ List edges = new List();
+ for (int i = 0; i < localPoints.Count; i++)
+ {
+ edges.Add(new Edge2D(localPoints[i], localPoints[(i + 1) % localPoints.Count]));
+ }
+ var centerTile = new Vector2(x * 16 + 8, -y * 16 - 8);
+ float depth;
+ Vector2 normal;
+ if (GeometryUtils.CirclePolygonIsCollide(center, radius, edges,
+ Vector2.Zero))
+ {
+ collided = true;
+ GeometryUtils.CirclePolygonCollisionInfo(center, radius, edges, localPoints.ToList(), out depth, out normal);
+
+ if (depth > maxDepth)
+ {
+ maxDepth = depth;
+ maxNormal = Vector2.Dot(maxNormal, center - centerTile) < 0 ? -normal : normal;
+ }
+ }
+ }
+ }
+ }
+ depth1 = 0;
+ normal1 = maxNormal;
+ return collided;
+ }
+ public static void GetSphereTileContactInfo(Vector2 center, float radius, PhysicsObject A, PhysicsObject B,
+ float deltaTime,
+ List outputList)
+ {
+ int minX = (int)Math.Floor((center.X - radius) / 16);
+ int maxX = (int)Math.Ceiling((center.X + radius) / 16);
+ int minY = (int)Math.Floor((-center.Y - radius) / 16);
+ int maxY = (int)Math.Ceiling((-center.Y + radius) / 16);
+
+ for (int x = Math.Max(minX, 0); x <= Math.Min(maxX, Main.maxTilesX - 1); x++)
+ {
+ for (int y = Math.Max(minY, 0); y <= Math.Min(maxY, Main.maxTilesY - 1); y++)
+ {
+ if (Main.tile[x, y] != null && Main.tile[x, y].HasTile && Main.tileSolid[Main.tile[x, y].TileType])
+ {
+ var localPoints = GenerateHalfBrick(x, y);
+ List edges = new List();
+ for (int i = 0; i < localPoints.Count; i++)
+ {
+ edges.Add(new Edge2D(localPoints[i], localPoints[(i + 1) % localPoints.Count]));
+ }
+ var centerTile = new Vector2(x * 16 + 8, -y * 16 - 8);
+ float depth;
+ Vector2 normal;
+ if (GeometryUtils.CirclePolygonCollisionInfo(center, radius, edges, localPoints.ToList(), out depth, out normal))
+ {
+ var e = new CollisionEvent2D()
+ {
+ Time = 0,
+ Source = A,
+ Target = B,
+ LocalOffsetSrc = Vector2.Zero,
+ LocalOffsetTarget = Vector2.Zero,
+ Normal = Vector2.Dot(normal, center - centerTile) < 0 ? -normal : normal,
+ Position = Vector2.Zero,
+ Depth = depth,
+ };
+ float weightA = e.Source.RigidBody.InvMass / (e.Source.RigidBody.InvMass + e.Target.RigidBody.InvMass);
+ float weightB = e.Target.RigidBody.InvMass / (e.Source.RigidBody.InvMass + e.Target.RigidBody.InvMass);
+ e.Source.RigidBody.MoveBody(e.Normal * weightA * e.Depth, deltaTime);
+ e.Target.RigidBody.MoveBody(-e.Normal * weightB * e.Depth, deltaTime);
+
+ List> contacts = new List>();
+ GeometryUtils.CirclePolygonContactInfo(e.Source.RigidBody.CentroidWorldSpace, radius, edges, localPoints.ToList(), centerTile, contacts);
+ foreach (var c in contacts)
+ {
+ outputList.Add(new CollisionEvent2D(e)
+ {
+ LocalOffsetSrc = c.Key,
+ LocalOffsetTarget = c.Value,
+ });
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/GeometryUtils.cs b/Sources/Everglow.Core/Physics/PBEngine/GeometryUtils.cs
new file mode 100644
index 000000000..e2a4747c4
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/GeometryUtils.cs
@@ -0,0 +1,401 @@
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria;
+
+namespace Everglow.Commons.Physics.PBEngine
+{
+ public static class GeometryUtils
+ {
+ public static bool ApproxEqual(float a, float b)
+ {
+ return Math.Abs(a - b) < 1e-6;
+ }
+ ///
+ /// Compute ab^T
+ ///
+ ///
+ ///
+ ///
+ public static Matrix3x3 OuterProduct(Vector3 a, Vector3 b)
+ {
+ return new Matrix3x3
+ {
+ [0, 0] = a.X * b.X,
+ [0, 1] = a.X * b.Y,
+ [0, 2] = a.X * b.Z,
+ [1, 0] = a.Y * b.X,
+ [1, 1] = a.Y * b.Y,
+ [1, 2] = a.Y * b.Z,
+ [2, 0] = a.Z * b.X,
+ [2, 1] = a.Z * b.Y,
+ [2, 2] = a.Z * b.Z
+ };
+ }
+
+ ///
+ /// Compute ab^T
+ ///
+ ///
+ ///
+ ///
+ public static Matrix2x2 OuterProduct(Vector2 a, Vector2 b)
+ {
+ return new Matrix2x2
+ {
+ [0, 0] = a.X * b.X,
+ [0, 1] = a.X * b.Y,
+ [1, 0] = a.Y * b.X,
+ [1, 1] = a.Y * b.Y,
+ };
+ }
+
+
+ public static float Cross(this Vector2 a, Vector2 b)
+ {
+ return a.X * b.Y - a.Y * b.X;
+ }
+
+
+ public static void Blit(Texture2D source, RenderTarget2D dest, Effect effect, string pass)
+ {
+ var sb = Main.spriteBatch;
+ var gd = Main.graphics.GraphicsDevice;
+ gd.SetRenderTarget(dest);
+ gd.Clear(Color.Transparent);
+ if (effect != null)
+ {
+ sb.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
+ effect.CurrentTechnique.Passes[pass].Apply();
+ sb.Draw(source, dest.Bounds, Color.White);
+ sb.End();
+ }
+ else
+ {
+ sb.Begin();
+ sb.Draw(source, dest.Bounds, Color.White);
+ sb.End();
+ }
+
+ }
+
+ ///
+ /// The linear velocity corresponding to given angular velocity and arm
+ ///
+ ///
+ ///
+ public static Vector2 AnuglarVelocityToLinearVelocity(Vector2 a, float w)
+ {
+ return new Vector2(-a.Y, a.X) * w;
+ }
+
+ public static Vector2 Rotate90(Vector2 a)
+ {
+ return new Vector2(-a.Y, a.X);
+ }
+
+ public static Vector2 ProjectPointOnSegment(Vector2 p, Vector2 start, Vector2 end)
+ {
+ var u = (end - start).SafeNormalize(Vector2.Zero);
+ return start + Vector2.Dot(u, p - start) * u;
+ }
+
+ public static float PointSignedDistanceToLine(Vector2 p, Vector2 start, Vector2 end)
+ {
+ Vector2 ab = end - start;
+ Vector2 ax = p - start;
+
+ float crossProductMagnitude = GeometryUtils.Cross(ab, ax);
+ float ABLength = ab.Length();
+
+ return -crossProductMagnitude / ABLength;
+ }
+
+ public static float PointSignedDistanceToSegment(Vector2 p, Vector2 start, Vector2 end)
+ {
+ var u = (end - start).SafeNormalize(Vector2.Zero);
+ float d = Vector2.Dot(u, p - start);
+ float sign = GeometryUtils.Cross(u, p - start) > 0 ? -1 : 1;
+ if (d <= 0)
+ {
+ return Vector2.Distance(p, start) * sign;
+ }
+ else if (d >= Vector2.Distance(start, end))
+ {
+ return Vector2.Distance(p, end) * sign;
+ }
+ return (p - (start + d * u)).Length() * sign;
+ }
+
+ public static float PointDistance2ToSegment(Vector2 p, Vector2 start, Vector2 end)
+ {
+ var u = (end - start).SafeNormalize(Vector2.Zero);
+ float d = Vector2.Dot(u, p - start);
+ if (d <= 0)
+ {
+ return Vector2.DistanceSquared(p, start);
+ }
+ else if (d * d >= Vector2.DistanceSquared(start, end))
+ {
+ return Vector2.DistanceSquared(p, end);
+ }
+ return (p - (start + d * u)).LengthSquared();
+ }
+ public static float PointDistance2ToSegmentWithClip(Vector2 p, Vector2 start, Vector2 end)
+ {
+ var u = (end - start).SafeNormalize(Vector2.Zero);
+ float d = Vector2.Dot(u, p - start);
+ if (d <= 0)
+ {
+ return float.PositiveInfinity;
+ }
+ else if (d * d >= Vector2.DistanceSquared(start, end))
+ {
+ return float.PositiveInfinity;
+ }
+ return (p - (start + d * u)).LengthSquared();
+ }
+
+ public static void CirclePolygonContactInfo(Vector2 cSphere, float radius, List edges,
+ List corners, Vector2 centerPoly,
+ List> localPositions)
+ {
+ float minDepth = float.PositiveInfinity;
+ foreach (var edge in edges)
+ {
+ float d = GeometryUtils.PointDistance2ToSegmentWithClip(cSphere, edge._pA, edge._pB);
+ if (d < minDepth)
+ {
+ minDepth = d;
+ }
+ }
+ foreach (var v in corners)
+ {
+ float d = Vector2.DistanceSquared(v, cSphere);
+ if (d < minDepth)
+ {
+ minDepth = d;
+ }
+ }
+
+ foreach (var edge in edges)
+ {
+ float d = GeometryUtils.PointDistance2ToSegmentWithClip(cSphere, edge._pA, edge._pB);
+ if (d == minDepth)
+ {
+ var p = GeometryUtils.ProjectPointOnSegment(cSphere, edge._pA, edge._pB);
+ localPositions.Add(new KeyValuePair(
+ (p - cSphere).SafeNormalize(Vector2.Zero) * radius,
+ p - centerPoly
+ ));
+ }
+ }
+ foreach (var v in corners)
+ {
+ float d = Vector2.DistanceSquared(v, cSphere);
+ if (d == minDepth)
+ {
+ localPositions.Add(new KeyValuePair(
+ (v - cSphere).SafeNormalize(Vector2.Zero) * radius,
+ v - centerPoly
+ ));
+ }
+ }
+ }
+
+ public static bool CirclePolygonCollisionInfo(Vector2 cSphere, float radius, List edges, List corners,
+ out float depth, out Vector2 normal)
+ {
+ float maxDepth = float.NegativeInfinity;
+ float maxDepth2 = float.NegativeInfinity;
+ Edge2D keyEdge = null;
+ foreach (var edge in edges)
+ {
+ float d = GeometryUtils.PointSignedDistanceToLine(cSphere, edge._pA, edge._pB);
+ float d2 = GeometryUtils.PointSignedDistanceToSegment(cSphere, edge._pA, edge._pB);
+ if (d2 > maxDepth2)
+ {
+ maxDepth2 = d2;
+ }
+ if (d > maxDepth)
+ {
+ maxDepth = d;
+ keyEdge = edge;
+ }
+ }
+
+ normal = keyEdge.GetNormal();
+ depth = radius - maxDepth;
+ if (maxDepth2 > radius)
+ {
+ return false;
+ }
+
+ foreach (var corner in corners)
+ {
+ float d = Vector2.Distance(corner, cSphere);
+ if (d <= radius && d > maxDepth)
+ {
+ maxDepth = d;
+ normal = Vector2.Normalize(cSphere - corner);
+ depth = radius - maxDepth;
+ }
+ }
+ return maxDepth < radius;
+ }
+
+ public static bool CirclePolygonIsCollide(Vector2 cSphere, float radius, List edges, Vector2 centerPoly)
+ {
+ float maxDepth = float.NegativeInfinity;
+ foreach (var edge in edges)
+ {
+ float d = GeometryUtils.PointSignedDistanceToSegment(cSphere, edge._pA, edge._pB);
+ if (d > maxDepth)
+ {
+ maxDepth = d;
+ }
+ }
+ return maxDepth < radius;
+ }
+
+ private static (float, float) GetProjectedInterval(List vertices, Vector2 start, Vector2 dir)
+ {
+ float v = Vector2.Dot(dir, vertices[0] - start);
+ float minA = v, maxA = v;
+ for (int i = 1; i < vertices.Count; i++)
+ {
+ float x = Vector2.Dot(dir, vertices[i] - start);
+ minA = Math.Min(minA, x);
+ maxA = Math.Max(maxA, x);
+ }
+ return (minA, maxA);
+ }
+
+ public static bool PolygonPolygonCollisionInfo(List edgesA, List cornersA,
+ List edgesB, List cornersB, out float depth, out Vector2 normal)
+ {
+ depth = float.PositiveInfinity;
+ normal = Vector2.Zero;
+ for (int i = 0; i < edgesA.Count; i++)
+ {
+ Edge2D edge = edgesA[i];
+ Vector2 axis = edge.GetNormal();
+
+ var (amin, amax) = GetProjectedInterval(cornersA, edge._pA, axis);
+ var (bmin, bmax) = GetProjectedInterval(cornersB, edge._pA, axis);
+
+ if (Math.Max(amin, bmin) > Math.Min(amax, bmax))
+ {
+ return false;
+ }
+
+ float d = Math.Min(amax, bmax) - Math.Max(amin, bmin);
+ if (d < depth)
+ {
+ depth = d;
+ normal = axis;
+ }
+ }
+ for (int i = 0; i < edgesB.Count; i++)
+ {
+ Edge2D edge = edgesB[i];
+ Vector2 axis = edge.GetNormal();
+
+ var (amin, amax) = GetProjectedInterval(cornersA, edge._pA, axis);
+ var (bmin, bmax) = GetProjectedInterval(cornersB, edge._pA, axis);
+
+ if (Math.Max(amin, bmin) > Math.Min(amax, bmax))
+ {
+ return false;
+ }
+
+ float d = Math.Min(amax, bmax) - Math.Max(amin, bmin);
+ if (d < depth)
+ {
+ depth = d;
+ normal = axis;
+ }
+ }
+ return true;
+ }
+
+ public static void PolygonPolygonContactInfo(List edgesA, List cornersA,
+ List edgesB, List cornersB,
+ Vector2 polyCenterA, Vector2 polyCenterB, List> localPositions)
+ {
+ float closestDistance = float.PositiveInfinity;
+ foreach (var curPoint in cornersA)
+ {
+ foreach (var curEdge in edgesB)
+ {
+ float dist = GeometryUtils.PointDistance2ToSegment(curPoint, curEdge._pA, curEdge._pB);
+ if (dist < closestDistance)
+ {
+ closestDistance = dist;
+ localPositions.Clear();
+ localPositions.Add(new KeyValuePair(
+ curPoint - polyCenterA,
+ GeometryUtils.ProjectPointOnSegment(curPoint, curEdge._pA, curEdge._pB)
+ - polyCenterB
+ ));
+ }
+ else if (Math.Abs(dist - closestDistance) < 1e-6)
+ {
+ localPositions.Add(new KeyValuePair(
+ curPoint - polyCenterA,
+ GeometryUtils.ProjectPointOnSegment(curPoint, curEdge._pA, curEdge._pB)
+ - polyCenterB
+ ));
+ }
+ }
+ }
+ foreach (var curPoint in cornersB)
+ {
+ foreach (var curEdge in edgesA)
+ {
+ float dist = GeometryUtils.PointDistance2ToSegment(curPoint, curEdge._pA, curEdge._pB);
+ if (dist < closestDistance)
+ {
+ closestDistance = dist;
+ localPositions.Clear();
+ localPositions.Add(new KeyValuePair(
+ GeometryUtils.ProjectPointOnSegment(curPoint, curEdge._pA, curEdge._pB) - polyCenterA,
+ curPoint - polyCenterB
+ ));
+ }
+ else if (Math.Abs(dist - closestDistance) < 1e-6)
+ {
+ localPositions.Add(new KeyValuePair(
+ GeometryUtils.ProjectPointOnSegment(curPoint, curEdge._pA, curEdge._pB) - polyCenterA,
+ curPoint - polyCenterB
+ ));
+ }
+ }
+ }
+ }
+
+ public static Vector2 ConvertToPhysicsSpace(Vector2 pos)
+ {
+ return new Vector2(pos.X, -pos.Y);
+ }
+
+ private static Random rng = new Random();
+
+ public static void FisherYatesShuffle(this IList list)
+ {
+ int n = list.Count;
+ while (n > 1)
+ {
+ n--;
+ int k = rng.Next(n + 1);
+ T value = list[k];
+ list[k] = list[n];
+ list[n] = value;
+ }
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/PhysicsObject.cs b/Sources/Everglow.Core/Physics/PBEngine/PhysicsObject.cs
new file mode 100644
index 000000000..e81ba2bf2
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/PhysicsObject.cs
@@ -0,0 +1,162 @@
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using Everglow.Commons.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine
+{
+ ///
+ /// 物理对象的容器,可以容纳Rigidbody,Collider等组件
+ /// 此外,它还是物理模拟的主体
+ ///
+ public class PhysicsObject
+ {
+ ///
+ /// 物理对象的几何组件,用于碰撞检测和质心计算等
+ ///
+ public Collider2D Collider
+ {
+ get => _collider;
+ }
+
+ ///
+ /// 物理对象的刚体物理组件,用于存储和模拟刚体数据
+ ///
+ public RigidBody2D RigidBody
+ {
+ get => _rigidBody;
+ }
+
+ ///
+ /// 物体的质心位置
+ ///
+ public Vector2 Position
+ {
+ get => _rigidBody.CentroidWorldSpace;
+ set => _rigidBody.CentroidWorldSpace = value;
+ }
+
+ ///
+ /// 物体的旋转,绕着质心
+ ///
+ public float Rotation
+ {
+ get => _rotation;
+ set => _rotation = value;
+ }
+
+ ///
+ /// 物体在迭代开始的时候的位置
+ ///
+ public Vector2 OldPosition
+ {
+ get => _oldPos;
+ set => _oldPos = value;
+ }
+
+ ///
+ /// 物体在迭代开始的时候的旋转
+ ///
+ public float OldRotation
+ {
+ get => _oldRot;
+ set => _oldRot = value;
+ }
+
+ ///
+ /// 物体的GUID
+ ///
+ public int GUID
+ {
+ get => _guid;
+ set => _guid = value;
+ }
+
+ ///
+ /// 物体的碰撞组名字
+ ///
+ public string Tag
+ {
+ get => _tag;
+ set => _tag = value;
+ }
+
+ private Collider2D _collider;
+ private RigidBody2D _rigidBody;
+ private Vector2 _oldPos;
+ private float _rotation;
+ private float _oldRot;
+ private int _guid;
+ private string _tag;
+
+ public PhysicsObject(Collider2D collider, RigidBody2D rigidBody)
+ {
+ _collider = collider;
+ _rigidBody = rigidBody;
+ _tag = "Default";
+
+ if (_rigidBody == null)
+ {
+ _rigidBody = new RigidBody2D(1)
+ {
+ MovementType = MovementType.Static,
+ UseGravity = false,
+ };
+ }
+
+ _collider.ParentObject = this;
+ _rigidBody.ParentObject = this;
+ }
+
+ public void Initialize()
+ {
+ _rigidBody?.Initialize();
+ }
+
+ public void RecordOldState()
+ {
+ _oldPos = Position;
+ _oldRot = _rotation;
+ }
+
+ public List GetWireFrameWires()
+ {
+ List wires = _collider.GetWireFrameWires();
+ var R = Matrix2x2.CreateRotationMatrix(_rotation);
+ for (int i = 0; i < wires.Count; i++)
+ {
+ wires[i] = R.Multiply(wires[i]) + Position;
+ }
+ return wires;
+ }
+ public void CleanUp()
+ {
+ _rigidBody?.CleanUp();
+ _rotation = MathHelper.WrapAngle(_rotation);
+ }
+ public void Update(float deltaTime)
+ {
+ _rigidBody?.Update(deltaTime);
+ }
+
+ public void ApplyGravity(Vector2 gravity)
+ {
+ if(_rigidBody != null)
+ {
+ if (_rigidBody.UseGravity)
+ {
+ _rigidBody.ApplyForce(gravity * _rigidBody.Mass);
+ }
+ }
+ }
+
+ public Vector2 LocalToWorldPos(Vector2 localPos)
+ {
+ return _rigidBody.CentroidWorldSpace + Matrix2x2.CreateRotationMatrix(_rotation).Multiply(localPos);
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs b/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
new file mode 100644
index 000000000..f29270279
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
@@ -0,0 +1,229 @@
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Collision.BroadPhase;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using Everglow.Commons.Physics.PBEngine.Constrains;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine
+{
+ ///
+ /// 用于物理模拟的世界,可以设置各种世界属性,添加和管理物理对象
+ /// 其中最重要的模拟部分也是由这个类完成
+ ///
+ public class PhysicsSimulation
+ {
+ public const double EPS = 1e-6;
+ public const int GAUSS_SEIDEL_ITERS = 8;
+
+ private List _dynamicPhysObjects;
+ private List _staticPhysObjects;
+ private List _constrains;
+ private BroadPhase _broadPhase;
+ private float _gravity;
+
+ private Stopwatch _stopwatchPreIntegration;
+ private Stopwatch _stopwatchBroadPhase;
+ private Stopwatch _stopwatchNarrowPhase;
+ private readonly double _ticksPerMillisecond;
+
+ ///
+ /// 用于性能检测,对各个阶段的耗时进行统计
+ ///
+ public double MeasuredPreIntegrationTimeInMs
+ {
+ get => _stopwatchPreIntegration.ElapsedTicks / _ticksPerMillisecond;
+ }
+ public double MeasuredBroadPhaseTimeInMs
+ {
+ get => _stopwatchBroadPhase.ElapsedTicks / _ticksPerMillisecond;
+ }
+ public double MeasuredNarrowPhaseTimeInMs
+ {
+ get => _stopwatchNarrowPhase.ElapsedTicks / _ticksPerMillisecond;
+ }
+
+ public PhysicsSimulation()
+ {
+ _dynamicPhysObjects = new List();
+ _staticPhysObjects = new List();
+ _constrains = new List();
+ _broadPhase = new BruteForceDetect(CollisionGraph.DefualtGraph);
+ _gravity = 9.8f;
+
+ _stopwatchPreIntegration = new Stopwatch();
+ _stopwatchBroadPhase = new Stopwatch();
+ _stopwatchNarrowPhase = new Stopwatch();
+
+ _ticksPerMillisecond = Stopwatch.Frequency / 1000.0;
+ }
+
+ public PhysicsSimulation(CollisionGraph graph)
+ : this()
+ {
+ _broadPhase = new BruteForceDetect(graph);
+ }
+
+ ///
+ /// 向世界添加物理对象,如果对象没有刚体部件,那么认为是静态物体
+ ///
+ ///
+ public void AddPhysicsObject(PhysicsObject pobj)
+ {
+ pobj.GUID = _dynamicPhysObjects.Count + _staticPhysObjects.Count;
+ if (pobj.RigidBody.MovementType == MovementType.Static)
+ {
+ _staticPhysObjects.Add(pobj);
+ }
+ else
+ {
+ _dynamicPhysObjects.Add(pobj);
+ }
+ pobj.Initialize();
+ }
+
+ ///
+ /// 向物理世界添加约束对象
+ ///
+ ///
+ public void AddConstrain(Constrain constrain)
+ {
+ _constrains.Add(constrain);
+ }
+
+ ///
+ /// Initialize physical object properties
+ ///
+ public void Initialize()
+ {
+ foreach (PhysicsObject pobj in _dynamicPhysObjects)
+ {
+ pobj.Initialize();
+ }
+ }
+
+ ///
+ /// 模拟一个完整步长,内部会分为多个子步长
+ ///
+ ///
+ public void Update(float deltaTime)
+ {
+ foreach (PhysicsObject pobj in _dynamicPhysObjects)
+ {
+ pobj.ApplyGravity(new Vector2(0, -_gravity));
+ }
+
+ _stopwatchPreIntegration.Reset();
+ _stopwatchBroadPhase.Reset();
+ _stopwatchNarrowPhase.Reset();
+ float dt = deltaTime / GAUSS_SEIDEL_ITERS;
+ for (int i = 0; i < GAUSS_SEIDEL_ITERS; i++)
+ {
+ _stopwatchPreIntegration.Start();
+ PreIntegration(dt);
+ _stopwatchPreIntegration.Stop();
+
+ Resolve(dt, _stopwatchBroadPhase, _stopwatchNarrowPhase);
+ }
+ CleanThisFrame();
+ }
+
+ public void CleanThisFrame()
+ {
+ CleanUp();
+ }
+
+ public List GetCurrentWireFrames()
+ {
+ List result = new List();
+ foreach (PhysicsObject pobj in _dynamicPhysObjects)
+ {
+ result.AddRange(pobj.GetWireFrameWires());
+ }
+ foreach (PhysicsObject pobj in _staticPhysObjects)
+ {
+ result.AddRange(pobj.GetWireFrameWires());
+ }
+ foreach (Constrain joint in _constrains)
+ {
+ result.AddRange(joint.GetDrawMesh());
+ }
+ return result;
+ }
+
+ ///
+ /// 进行预积分,先模拟一个步长
+ ///
+ ///
+ private void PreIntegration(float deltaTime)
+ {
+ foreach (PhysicsObject pobj in _staticPhysObjects)
+ {
+ pobj.RecordOldState();
+ }
+ foreach (PhysicsObject pobj in _dynamicPhysObjects)
+ {
+ pobj.RecordOldState();
+ pobj.Update(deltaTime);
+ }
+ }
+
+ ///
+ /// 解算所有物体的约束条件,并且做出响应
+ ///
+ ///
+ ///
+ ///
+ private void Resolve(float deltaTime, Stopwatch broadPhase, Stopwatch narrowPhase)
+ {
+ broadPhase.Start();
+ _broadPhase.Prepare(_dynamicPhysObjects.Concat(_staticPhysObjects).ToList(), deltaTime);
+ var pairs = _broadPhase.GetCollisionPairs(deltaTime);
+ broadPhase.Stop();
+
+ narrowPhase.Start();
+ foreach (var joint in _constrains)
+ {
+ joint.Apply(deltaTime);
+ }
+ foreach (var pair in pairs)
+ {
+ CollisionInfo info;
+ if (pair.Key.TestCollisionCondition(pair.Value, deltaTime, out info))
+ {
+ float weightA = info.Source.RigidBody.InvMass / (info.Source.RigidBody.InvMass + info.Target.RigidBody.InvMass);
+ float weightB = info.Target.RigidBody.InvMass / (info.Source.RigidBody.InvMass + info.Target.RigidBody.InvMass);
+ //if (weightA != 0 && weightB != 0)
+ // weightA = weightB = 0.5f;
+
+ info.Source.RigidBody.MoveBody(info.Normal * weightA * info.Depth, deltaTime);
+ info.Target.RigidBody.MoveBody(-info.Normal * weightB * info.Depth, deltaTime);
+
+ List events;
+ pair.Key.GetContactInfo(info, deltaTime, out events);
+ ApplyConstrains(events, pair.Key.ParentObject, deltaTime);
+ }
+ }
+ narrowPhase.Stop();
+ }
+
+ private void ApplyConstrains(List events, PhysicsObject pobj, float deltaTime)
+ {
+ if (deltaTime == 0)
+ {
+ return;
+ }
+ pobj.RigidBody.RespondToEvents(events, deltaTime);
+ }
+ private void CleanUp()
+ {
+ foreach (PhysicsObject pobj in _dynamicPhysObjects)
+ {
+ pobj.CleanUp();
+ }
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Constrain/JointPlayground.cs b/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Constrain/JointPlayground.cs
new file mode 100644
index 000000000..d4054426c
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Constrain/JointPlayground.cs
@@ -0,0 +1,229 @@
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using Everglow.Commons.Physics.PBEngine.Constrains;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.PlayGround.Constrain
+{
+ ///
+ /// 储存了一些测试约束的场景
+ ///
+ public class JointPlayground
+ {
+ public static PhysicsSimulation SimpleJoint()
+ {
+ var world = new PhysicsSimulation();
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(500, 660);
+ dynamicBox.Rotation = 0.0f;
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(300, 32), null);
+ staticPlane1.Position = new Vector2(512, 700);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var joint = new JointConstrain(staticPlane1, dynamicBox, new Vector2(0, -40), new Vector2(0, 64));
+ world.AddConstrain(joint);
+
+ return world;
+ }
+
+ public static PhysicsSimulation SimpleJointMultiple()
+ {
+ var world = new PhysicsSimulation();
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(32, 32), null);
+ staticPlane1.Position = new Vector2(512, 700);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(500, 600);
+ dynamicBox.Rotation = 0.0f;
+ world.AddPhysicsObject(dynamicBox);
+
+ var dynamicBox1 = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox1.Position = new Vector2(500, 500);
+ dynamicBox1.Rotation = 0.0f;
+ world.AddPhysicsObject(dynamicBox1);
+
+ var joint = new JointConstrain(staticPlane1, dynamicBox, new Vector2(0, -50), new Vector2(0, 50));
+ world.AddConstrain(joint);
+
+ var joint2 = new JointConstrain(dynamicBox, dynamicBox1, new Vector2(0, -70), new Vector2(0, 70));
+ world.AddConstrain(joint2);
+
+ //var kPlane = new PhysicsObject(
+ // new BoxCollider(200, 32), null);
+ //kPlane.Position = new Vector2(512, 400);
+ //kPlane.Rotation = 0;
+ //kPlane.RigidBody.ApplyAngularVelocity(0.9f);
+ //kPlane.RigidBody.MovementType = Collision.MovementType.Kinematic;
+ //world.AddPhysicsObject(kPlane);
+ return world;
+ }
+
+ public static PhysicsSimulation DynamicJoints()
+ {
+ var world = new PhysicsSimulation();
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(500, 500);
+ dynamicBox.Rotation = 0.2f;
+ world.AddPhysicsObject(dynamicBox);
+
+ var dynamicBox1 = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox1.Position = new Vector2(500, 440);
+ dynamicBox1.Rotation = 0.3f;
+ world.AddPhysicsObject(dynamicBox1);
+
+ var joint2 = new JointConstrain(dynamicBox, dynamicBox1, new Vector2(0, -50), new Vector2(0, 50));
+ world.AddConstrain(joint2);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(700, 32), null);
+ staticPlane1.Position = new Vector2(512, 300);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ return world;
+ }
+
+ public static PhysicsSimulation NewtonPendulum()
+ {
+ var world = new PhysicsSimulation();
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(512, 32), null);
+ staticPlane1.Position = new Vector2(512, 800);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ for (int i = 0; i < 5; i++)
+ {
+ var dynamicBox = new PhysicsObject(
+ new SphereCollider(32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512 + 64 * (i - 2), 600);
+ dynamicBox.Rotation = 0.0f;
+ world.AddPhysicsObject(dynamicBox);
+
+ if (i == 0)
+ {
+ dynamicBox.RigidBody.LinearVelocity = new Vector2(-50, 0);
+ }
+
+ var joint1 = new JointConstrain(staticPlane1, dynamicBox, new Vector2(64 * (i - 2), -16), new Vector2(0, 200));
+ world.AddConstrain(joint1);
+ }
+
+
+ //var dynamicBox1 = new PhysicsObject(
+ // new SphereCollider(32), new RigidBody2D(256));
+ //dynamicBox1.Position = new Vector2(512, 584);
+ //dynamicBox1.Rotation = 0.0f;
+ //world.AddPhysicsObject(dynamicBox1);
+
+ //var dynamicBox2 = new PhysicsObject(
+ // new SphereCollider(32), new RigidBody2D(256));
+ //dynamicBox2.Position = new Vector2(576, 584);
+ //dynamicBox2.Rotation = 0.0f;
+ //world.AddPhysicsObject(dynamicBox2);
+
+
+
+
+
+ //var joint2 = new Joint(staticPlane1, dynamicBox1, new Vector2(0, -16), new Vector2(0, 200));
+ //world.AddConstrain(joint2);
+
+ //var joint3 = new Joint(staticPlane1, dynamicBox2, new Vector2(64, -16), new Vector2(0, 200));
+ //world.AddConstrain(joint3);
+
+
+ return world;
+ }
+
+ public static PhysicsSimulation SimpleSpring()
+ {
+ var world = new PhysicsSimulation();
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(300, 100);
+ dynamicBox.Rotation = 0.0f;
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(300, 32), null);
+ staticPlane1.Position = new Vector2(512, 700);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var joint = new SpringConstrain(staticPlane1, dynamicBox, 29f, 200);
+ world.AddConstrain(joint);
+
+ var dynamicBox1 = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox1.Position = new Vector2(400, 10);
+ dynamicBox1.Rotation = 0.0f;
+ world.AddPhysicsObject(dynamicBox1);
+
+ var joint1 = new SpringConstrain(dynamicBox, dynamicBox1, 29f, 200);
+ world.AddConstrain(joint1);
+
+ return world;
+ }
+
+ public static PhysicsSimulation SpringTriganluar()
+ {
+ var world = new PhysicsSimulation();
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 64), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(300, 100);
+ dynamicBox.Rotation = 0.0f;
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(32, 32), null);
+ staticPlane1.Position = new Vector2(512, 700);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(32, 32), null);
+ staticPlane2.Position = new Vector2(212, 300);
+ staticPlane2.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane2);
+
+ var staticPlane3 = new PhysicsObject(
+new BoxCollider(32, 32), null);
+ staticPlane3.Position = new Vector2(812, 300);
+ staticPlane3.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane3);
+
+ var joint = new SpringConstrain(staticPlane1, dynamicBox, 29f, 200);
+ world.AddConstrain(joint);
+ var joint1 = new SpringConstrain(staticPlane2, dynamicBox, 29f, 200);
+ world.AddConstrain(joint1);
+
+ var joint2 = new SpringConstrain(staticPlane3, dynamicBox, 29f, 200);
+ world.AddConstrain(joint2);
+
+
+ return world;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround1.cs b/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround1.cs
new file mode 100644
index 000000000..57929b5c5
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround1.cs
@@ -0,0 +1,308 @@
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.PlayGround.Contact
+{
+ ///
+ /// 储存了一些物理引擎接触测试的场景
+ ///
+ public class ContactPlayGround1
+ {
+ public static PhysicsSimulation SimpleGround1()
+ {
+ var world = new PhysicsSimulation();
+
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512, 800);
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(300, 32), null);
+ staticPlane1.Position = new Vector2(512, 200);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ return world;
+ }
+
+ public static PhysicsSimulation InclinedGround()
+ {
+ var world = new PhysicsSimulation();
+
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512, 800);
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(600, 32), null);
+ staticPlane1.Position = new Vector2(512, 200);
+ staticPlane1.Rotation = 0.22f;
+ world.AddPhysicsObject(staticPlane1);
+
+ return world;
+ }
+
+ public static PhysicsSimulation MultipleInclinedGround()
+ {
+ var world = new PhysicsSimulation();
+
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512, 900);
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ staticPlane1.Position = new Vector2(300, 700);
+ staticPlane1.Rotation = -0.32f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ staticPlane2.Position = new Vector2(680, 200);
+ staticPlane2.Rotation = 0.32f;
+ world.AddPhysicsObject(staticPlane2);
+
+ return world;
+ }
+
+ public static PhysicsSimulation MultipleInclinedGround2()
+ {
+ var world = new PhysicsSimulation();
+
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512, 900);
+ world.AddPhysicsObject(dynamicBox);
+
+ for (int i = 0; i < 5; i++)
+ {
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ staticPlane1.Position = new Vector2(300, 700 - i * 200);
+ staticPlane1.Rotation = -0.32f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ staticPlane2.Position = new Vector2(680, 700 - i * 200 - 100);
+ staticPlane2.Rotation = 0.32f;
+ world.AddPhysicsObject(staticPlane2);
+ }
+ return world;
+ }
+
+ public static PhysicsSimulation MultipleInclinedGround3()
+ {
+ var world = new PhysicsSimulation();
+
+ for (int i = 0; i < 20; i++)
+ {
+ var dynamicBox = new PhysicsObject(
+ new SphereCollider(16), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512 + (i % 10) * 40, 900 + i / 10 * 40);
+ world.AddPhysicsObject(dynamicBox);
+ }
+
+ for (int i = 0; i < 5; i++)
+ {
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ staticPlane1.Position = new Vector2(300, 700 - i * 250);
+ staticPlane1.Rotation = -0.38f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ staticPlane2.Position = new Vector2(680, 700 - i * 250 - 125);
+ staticPlane2.Rotation = 0.38f;
+ world.AddPhysicsObject(staticPlane2);
+ }
+ return world;
+ }
+
+ public static PhysicsSimulation MultipleInclinedGroundSphere()
+ {
+ var world = new PhysicsSimulation();
+
+
+ for (int i = 0; i < 20; i++)
+ {
+ var dynamicBall = new PhysicsObject(
+ new SphereCollider(16), new RigidBody2D(256));
+ dynamicBall.Position = new Vector2(512, 800 + i * 40);
+ world.AddPhysicsObject(dynamicBall);
+ }
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(400, 32), null);
+ staticPlane1.Position = new Vector2(200, 400);
+ staticPlane1.Rotation = -0.78f;
+ world.AddPhysicsObject(staticPlane1);
+
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(400, 32), null);
+ staticPlane2.Position = new Vector2(400, 400);
+ staticPlane2.Rotation = 0.78f;
+ world.AddPhysicsObject(staticPlane2);
+
+ return world;
+ }
+
+ public static PhysicsSimulation DoubleSlope()
+ {
+ var world = new PhysicsSimulation();
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(162, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(300, 600);
+ world.AddPhysicsObject(dynamicBox);
+
+ var dynamicBox1 = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox1.Position = new Vector2(300, 760);
+ dynamicBox1.RigidBody.ApplyForce(new Vector2(100, 0));
+ world.AddPhysicsObject(dynamicBox1);
+
+
+ for (int i = 0; i < 100; i++)
+ {
+ var dynamicBox2 = new PhysicsObject(
+ new BoxCollider(55, 32), new RigidBody2D(256));
+ dynamicBox2.Position = new Vector2(350, 700 + 36 * i);
+ dynamicBox2.RigidBody.ApplyForce(new Vector2(100, 0));
+ world.AddPhysicsObject(dynamicBox2);
+ }
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(400, 32), null);
+ staticPlane1.Position = new Vector2(200, 400);
+ staticPlane1.Rotation = -0.78f;
+ world.AddPhysicsObject(staticPlane1);
+
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(400, 32), null);
+ staticPlane2.Position = new Vector2(400, 400);
+ staticPlane2.Rotation = 0.78f;
+ world.AddPhysicsObject(staticPlane2);
+
+ return world;
+ }
+
+ public static PhysicsSimulation SimpleKinematic()
+ {
+ var world = new PhysicsSimulation();
+
+ for (int i = 0; i < 200; i++)
+ {
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512 + (i % 10) * 35, 900 + i / 10 * 35);
+ world.AddPhysicsObject(dynamicBox);
+ }
+
+ var kPlane = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ kPlane.Position = new Vector2(512, 512);
+ kPlane.Rotation = 0;
+ kPlane.RigidBody.ApplyAngularVelocity(0.9f);
+ kPlane.RigidBody.MovementType = Collision.MovementType.Kinematic;
+ world.AddPhysicsObject(kPlane);
+
+ var sPlane = new PhysicsObject(
+ new BoxCollider(32, 600), null);
+ sPlane.Position = new Vector2(0, 512);
+ sPlane.Rotation = 0;
+ world.AddPhysicsObject(sPlane);
+
+ var sPlane2 = new PhysicsObject(
+ new BoxCollider(32, 600), null);
+ sPlane2.Position = new Vector2(1024, 512);
+ sPlane2.Rotation = 0;
+ world.AddPhysicsObject(sPlane2);
+
+ var sPlane1 = new PhysicsObject(
+ new BoxCollider(1024, 32), null);
+ sPlane1.Position = new Vector2(512, 0);
+ sPlane1.Rotation = 0;
+ world.AddPhysicsObject(sPlane1);
+ return world;
+ }
+
+ public static PhysicsSimulation SimpleSphere()
+ {
+ var world = new PhysicsSimulation();
+
+ var dynamicBox = new PhysicsObject(
+ new SphereCollider(32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512, 800);
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(300, 32), null);
+ staticPlane1.Position = new Vector2(512, 200);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+ return world;
+ }
+
+ public static PhysicsSimulation SlopeSphere()
+ {
+ var world = new PhysicsSimulation();
+
+ var dynamicBox = new PhysicsObject(
+ new SphereCollider(32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512, 800);
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(300, 32), null);
+ staticPlane1.Position = new Vector2(512, 200);
+ staticPlane1.Rotation = 0.3f;
+ world.AddPhysicsObject(staticPlane1);
+ return world;
+ }
+
+ public static PhysicsSimulation SphereAndBox()
+ {
+ var world = new PhysicsSimulation();
+
+ for (int i = 0; i < 10; i++)
+ {
+ var dynamicBox = new PhysicsObject(
+ new SphereCollider(32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512 + (i - 5) * 50, 800);
+ world.AddPhysicsObject(dynamicBox);
+ }
+
+ for (int i = 0; i < 10; i++)
+ {
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512 + (i - 5) * 50, 700);
+ world.AddPhysicsObject(dynamicBox);
+ }
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(600, 32), null);
+ staticPlane1.Position = new Vector2(512, 200);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+ return world;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround2.cs b/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround2.cs
new file mode 100644
index 000000000..8d31c442f
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/PlayGround/Contact/ContactPlayGround2.cs
@@ -0,0 +1,110 @@
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Physics.PBEngine.PlayGround.Contact
+{
+ ///
+ /// 储存了一些物理引擎接触测试的场景
+ ///
+ public class ContactPlayGround2
+ {
+ public static PhysicsSimulation SphereStairCase()
+ {
+ var world = new PhysicsSimulation();
+
+
+ var dynamicBox = new PhysicsObject(
+ new SphereCollider(32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(512, 800);
+ dynamicBox.RigidBody.LinearVelocity = new Vector2(12, 0);
+ world.AddPhysicsObject(dynamicBox);
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(300, 32), null);
+ staticPlane1.Position = new Vector2(512, 400);
+ staticPlane1.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane1);
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(100, 16), null);
+ staticPlane2.Position = new Vector2(700, 424);
+ staticPlane2.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane2);
+
+ var staticPlane3 = new PhysicsObject(
+ new BoxCollider(100, 16), null);
+ staticPlane3.Position = new Vector2(400, 424);
+ staticPlane3.Rotation = 0f;
+ world.AddPhysicsObject(staticPlane3);
+
+ return world;
+ }
+
+ public static PhysicsSimulation ExtractionTest()
+ {
+ var world = new PhysicsSimulation();
+
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(128, 32), new RigidBody2D(128));
+ dynamicBox.Position = new Vector2(300, 800);
+ dynamicBox.RigidBody.LinearVelocity = new Vector2(0, 0);
+ world.AddPhysicsObject(dynamicBox);
+
+ var dynamicball = new PhysicsObject(
+ new SphereCollider(32), new RigidBody2D(512));
+ dynamicball.Position = new Vector2(300, 900);
+ dynamicball.RigidBody.LinearVelocity = new Vector2(0, 0);
+ world.AddPhysicsObject(dynamicball);
+
+ var dynamicball2 = new PhysicsObject(
+ new SphereCollider(32), new RigidBody2D(512));
+ dynamicball2.Position = new Vector2(380, 900);
+ dynamicball2.RigidBody.LinearVelocity = new Vector2(0, 0);
+ world.AddPhysicsObject(dynamicball2);
+
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(400, 32), null);
+ staticPlane1.Position = new Vector2(200, 400);
+ staticPlane1.Rotation = -0.78f;
+ world.AddPhysicsObject(staticPlane1);
+
+
+ var staticPlane2 = new PhysicsObject(
+ new BoxCollider(400, 32), null);
+ staticPlane2.Position = new Vector2(400, 400);
+ staticPlane2.Rotation = 0.78f;
+ world.AddPhysicsObject(staticPlane2);
+
+ return world;
+ }
+
+ public static PhysicsSimulation MoveWithPad()
+ {
+ var world = new PhysicsSimulation();
+
+
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(32, 32), new RigidBody2D(256));
+ dynamicBox.Position = new Vector2(400, 700);
+ dynamicBox.RigidBody.LinearVelocity = new Vector2(0, 0);
+ world.AddPhysicsObject(dynamicBox);
+
+ var kPlane = new PhysicsObject(
+ new BoxCollider(500, 32), null);
+ kPlane.Position = new Vector2(512, 512);
+ kPlane.Rotation = 0;
+ kPlane.RigidBody.Drag = 0;
+ kPlane.RigidBody.LinearVelocity = new Vector2(10, 0);
+ kPlane.RigidBody.MovementType = Collision.MovementType.Kinematic;
+ world.AddPhysicsObject(kPlane);
+
+ return world;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs b/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
new file mode 100644
index 000000000..43e294f08
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
@@ -0,0 +1,584 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing.Printing;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using Terraria;
+
+namespace Everglow.Commons.Physics.PBEngine
+{
+ ///
+ /// 2D刚体物理组件,用于实际的刚体运动模拟和响应的模块
+ ///
+ public class RigidBody2D
+ {
+ ///
+ /// 指向物理对象的指针
+ ///
+ public PhysicsObject ParentObject
+ {
+ get => _bindObject;
+ set => _bindObject = value;
+ }
+
+ ///
+ /// 世界坐标下的质心坐标(指物理世界
+ ///
+ public Vector2 CentroidWorldSpace
+ {
+ get => _globalCentroid;
+ set => _globalCentroid = value;
+ }
+
+ ///
+ /// 质量
+ ///
+ public float Mass
+ {
+ get => _mass;
+ set => _mass = value;
+ }
+
+ ///
+ /// 质量的倒数
+ ///
+ public float InvMass
+ {
+ get => (MovementType == MovementType.Dynamic || MovementType == MovementType.Player) ? 1 / _mass : 0;
+ }
+
+ ///
+ /// 世界坐标下惯性张量的倒数
+ ///
+ public double GlobalInverseInertiaTensor
+ {
+ get => MovementType == MovementType.Dynamic ? _globalInverseInertiaTensor : 0;
+ }
+
+ ///
+ /// 是否启用重力
+ ///
+ public bool UseGravity
+ {
+ get; set;
+ }
+
+ ///
+ /// 线速度
+ ///
+ public Vector2 LinearVelocity
+ {
+ get => MovementType == MovementType.Static ? Vector2.Zero : _linearVelocity;
+ set => _linearVelocity = value;
+ }
+
+
+ ///
+ /// 角速度
+ ///
+ public float AngularVelocity
+ {
+ get => MovementType == MovementType.Static ? 0 : _angularVelocity;
+ set => _angularVelocity = value;
+ }
+
+ ///
+ /// 移动模式
+ ///
+ public MovementType MovementType
+ {
+ get; set;
+ }
+
+ ///
+ /// 线速度的阻尼
+ ///
+ public float Drag
+ {
+ get => _drag;
+ set => _drag = value;
+ }
+
+ ///
+ /// 角速度的阻尼
+ ///
+ public float AngularDrag
+ {
+ get => _angularDrag;
+ set => _angularDrag = value;
+ }
+
+ ///
+ /// 碰撞弹出的系数
+ ///
+ public float Stiffness
+ {
+ get => _stiffness;
+ set => _stiffness = value;
+ }
+
+ ///
+ /// 摩擦力系数
+ ///
+ public float Friction
+ {
+ get => _friction;
+ set => _friction = value;
+ }
+
+ private double _localInverseInertiaTensor;
+ private double _globalInverseInertiaTensor;
+
+ private Vector2 _globalCentroid;
+
+ private Vector2 _linearVelocity;
+ private float _angularVelocity;
+
+ private float _torque;
+ private Vector2 _force;
+ private float _mass;
+ private float _drag;
+ private float _angularDrag;
+ private float _stiffness;
+ private float _friction;
+
+ private List _impluses;
+
+ private bool _isAwake;
+
+ private PhysicsObject _bindObject;
+
+ public RigidBody2D(float mass)
+ {
+ _mass = mass;
+ MovementType = MovementType.Dynamic;
+ UseGravity = true;
+ _isAwake = true;
+ _linearVelocity = Vector2.Zero;
+ _angularVelocity = 0;
+ _drag = 0.06f;
+ _angularDrag = 0.06f;
+ _impluses = new List();
+ _stiffness = 0.5f;
+ _friction = 0.5f;
+ }
+
+
+ private void CalculateMassCentroidAndMoI()
+ {
+ _globalInverseInertiaTensor = _localInverseInertiaTensor = 1 / _bindObject.Collider.InertiaTensor(_mass);
+ }
+
+ public void Initialize()
+ {
+ CalculateMassCentroidAndMoI();
+ }
+
+ private void UpdateGlobalInertiaTensor()
+ {
+ // var R = Matrix2x2.CreateRotationMatrix(_rotation);
+ // _globalInertiaTensor = R.Multiply(_localInverseInertiaTensor).Multiply(R.Transpose());
+ _globalInverseInertiaTensor = _localInverseInertiaTensor;
+ }
+
+ ///
+ /// 进行一次运动积分
+ ///
+ ///
+ public void Update(float deltaTime)
+ {
+ if (MovementType == MovementType.Static)
+ {
+ return;
+ }
+
+ _angularVelocity += (float)(_globalInverseInertiaTensor * deltaTime * _torque);
+ _linearVelocity += deltaTime * _force / _mass;
+ // _oldRot = _rotation;
+
+ // _oldPos = _globalCentroid;
+ _globalCentroid += deltaTime * _linearVelocity;
+ _bindObject.Rotation += deltaTime * _angularVelocity;
+
+
+
+ Debug.Assert(!float.IsNaN(_linearVelocity.X) && !float.IsNaN(_linearVelocity.Y));
+ Debug.Assert(!float.IsNaN(_angularVelocity));
+
+ StabilizeBody();
+
+ // CollisionDetection(deltaTime);
+ // CollisionResponse(deltaTime);
+ }
+
+ private void StabilizeBody()
+ {
+ if (Math.Abs(_linearVelocity.X) < PhysicsSimulation.EPS
+ && Math.Abs(_linearVelocity.Y) < PhysicsSimulation.EPS)
+ {
+ _linearVelocity = Vector2.Zero;
+ }
+
+ if(Math.Abs(_angularVelocity) < PhysicsSimulation.EPS)
+ {
+ _angularVelocity = 0;
+ }
+ }
+
+ public void ApplyForce(Vector2 force)
+ {
+ _force += force;
+ }
+
+ public void CleanUp()
+ {
+ _torque = 0;
+ _force = Vector2.Zero;
+ _impluses.Clear();
+ // Main.NewText((_linearVelocity.LengthSquared() * _mass * 0.5f + _mass * 9.8f * _globalCentroid.Y).ToString("F1"));
+
+ _linearVelocity *= 1 - _drag * _drag;
+ _angularVelocity *= 1 - _angularDrag * _angularDrag;
+ }
+
+ //public void RespondToEvents(List events, float deltaTime)
+ //{
+ // var ri0 = events[0].LocalOffsetSrc;
+ // var rb0 = events[0].LocalOffsetTarget;
+ // var n0 = events[0].Normal;
+ // var va0 = _linearVelocity + Utils.AnuglarVelocityToLinearVelocity(ri0, _angularVelocity);
+ // var vb0 = events[0].Target.RigidBody._linearVelocity
+ // + Utils.AnuglarVelocityToLinearVelocity(rb0, events[0].Target.RigidBody._angularVelocity);
+ // float relv0_n = Vector2.Dot(va0 - vb0, n0);
+
+ // var ri1 = events[1].LocalOffsetSrc;
+ // var rb1 = events[1].LocalOffsetTarget;
+ // var n1 = events[1].Normal;
+ // var va1 = _linearVelocity + Utils.AnuglarVelocityToLinearVelocity(ri1, _angularVelocity);
+ // var vb1 = events[1].Target.RigidBody._linearVelocity
+ // + Utils.AnuglarVelocityToLinearVelocity(rb1, events[1].Target.RigidBody._angularVelocity);
+ // float relv1_n = Vector2.Dot(va1 - vb1, n1);
+ // Matrix2x2 matrix = new Matrix2x2()
+ // {
+ // [0, 0] = InvMass + events[0].Target.RigidBody.InvMass
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri0, n0))), n0)
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb0, (float)(events[0].Target.RigidBody.GlobalInverseInertiaTensor
+ // * Utils.Cross(rb0, n0))), n0),
+ // [0, 1] = InvMass * Vector2.Dot(n0, n1) + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri1, n1))), n0),
+
+ // [1, 0] = InvMass * Vector2.Dot(n0, n1) + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri1, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri0, n0))), n1),
+ // [1, 1] = InvMass + events[1].Target.RigidBody.InvMass
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri1, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri1, n1))), n1)
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb1, (float)(events[1].Target.RigidBody.GlobalInverseInertiaTensor
+ // * Utils.Cross(rb1, n1))), n1),
+ // };
+ // float C = 0.4f;
+ // var J = matrix.Inverse().Multiply(new Vector2(-(1 + C) * relv0_n, -(1 + C) * relv1_n));
+ // if (!J.HasNaNs())
+ // {
+ // AddImpluse(J.X * events[0].Normal, ri0, events[0].Time, events[0].Normal);
+ // AddImpluse(J.Y * events[1].Normal, ri1, events[1].Time, events[1].Normal);
+ // }
+ // var t = matrix.Multiply(J);
+ // if (true)
+ // ;
+ //}
+ public void ApplyAngularVelocity(float w)
+ {
+ _angularVelocity += w;
+ }
+ private void SolveContactImpluse(CollisionEvent2D e, int count, float deltaTime)
+ {
+ var ri = e.LocalOffsetSrc;
+ var rb = e.LocalOffsetTarget;
+
+ var v2 = GeometryUtils.AnuglarVelocityToLinearVelocity(ri, _angularVelocity);
+ var va = _linearVelocity + v2;
+ var vb = e.Target.RigidBody._linearVelocity
+ + GeometryUtils.AnuglarVelocityToLinearVelocity(rb, e.Target.RigidBody._angularVelocity);
+ var bias = 0.1f * Math.Max(e.Depth - 0.02f, 0) / deltaTime;
+
+
+ float va_n = Vector2.Dot(va - vb, e.Normal);
+ if (va_n >= 0)
+ {
+ e.NormalVelOld = 0;
+ return;
+ }
+ float stiffness = Math.Max(0, (_stiffness + e.Target.RigidBody.Stiffness) / 2);
+ float vnew_n = stiffness * Math.Max(-va_n - 20 * deltaTime, 0);
+
+ // (a × b) × c = (c • a)b - (c • b)a
+ double rAdotN = Vector2.Dot(GeometryUtils.Rotate90(ri), e.Normal);
+ double rBdotN = Vector2.Dot(GeometryUtils.Rotate90(rb), e.Normal);
+ double R1 = rAdotN * rAdotN * GlobalInverseInertiaTensor; // Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri, e.Normal))), e.Normal);
+ double R2 = rBdotN * rBdotN * e.Target.RigidBody.GlobalInverseInertiaTensor;//Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb, (float)(e.Target.RigidBody.GlobalInverseInertiaTensor
+ //* Utils.Cross(rb, e.Normal))), e.Normal);
+ double J_n = (vnew_n - va_n) / (InvMass + e.Target.RigidBody.InvMass + R1 + R2);
+ Vector2 J = (float)J_n * e.Normal / count;// + (float)J_t * va_t_unit;
+ e.NormalVelOld = (float)J_n;
+
+ // var offset = e.Position - (_globalCentroid + ri);
+ AddImpluse(J, ri, e.Target.RigidBody, -J, rb);
+ }
+
+ private void SolveFrictionImpluse(CollisionEvent2D e, int count, float deltaTime)
+ {
+ var ri = e.LocalOffsetSrc;
+ var rb = e.LocalOffsetTarget;
+
+ var v2 = GeometryUtils.AnuglarVelocityToLinearVelocity(ri, _angularVelocity);
+ var va = _linearVelocity + v2;
+ var vb = e.Target.RigidBody._linearVelocity
+ + GeometryUtils.AnuglarVelocityToLinearVelocity(rb, e.Target.RigidBody._angularVelocity);
+
+ if (e.NormalVelOld == 0)
+ {
+ return;
+ }
+
+ float vel_n = Vector2.Dot(va - vb, e.Normal);
+ Vector2 vt = (va - vb) - vel_n * e.Normal;
+ float vel_t = vt.Length();
+ float friction = Math.Max(0, (_friction + e.Target.RigidBody.Friction) / 2);
+
+ vt = vt.SafeNormalize(Vector2.Zero);
+
+ double effectiveMass = (InvMass + e.Target.RigidBody.InvMass
+ + Vector2.Dot(GeometryUtils.AnuglarVelocityToLinearVelocity(ri, (float)(GlobalInverseInertiaTensor
+ * GeometryUtils.Cross(ri, vt))), vt)
+ + Vector2.Dot(GeometryUtils.AnuglarVelocityToLinearVelocity(rb, (float)(e.Target.RigidBody.GlobalInverseInertiaTensor
+ * GeometryUtils.Cross(rb, vt))), vt));
+
+ // (a × b) × c = (c • a)b - (c • b)a
+ double J_n = -Math.Min(friction * e.NormalVelOld, vel_t / effectiveMass);
+ Vector2 J = (float)J_n * vt / count;// + (float)J_t * va_t_unit;
+
+ AddImpluse(J, ri, e.Target.RigidBody, -J, rb);
+ }
+
+ ///
+ /// 对接触事件进行响应
+ ///
+ ///
+ ///
+ public void RespondToEvents(List events, float deltaTime)
+ {
+ foreach (var e in events)
+ {
+ SolveContactImpluse(e, events.Count, deltaTime);
+ }
+ ApplyImpluses();
+ foreach (var e in events)
+ {
+ SolveFrictionImpluse(e, events.Count, deltaTime);
+ }
+ ApplyImpluses();
+ }
+
+ public void Integrate(float deltaTime)
+ {
+ if (MovementType == MovementType.Static)
+ {
+ return;
+ }
+ _bindObject.Rotation += deltaTime * _angularVelocity;
+ _globalCentroid += deltaTime * _linearVelocity;
+ _bindObject.Position = _globalCentroid;
+ }
+
+ //public void ResolveImpluse(float deltaTime)
+ //{
+ // if (_impluses.Count == 0)
+ // {
+ // return;
+ // }
+ // //_bindObject.Rotation = _bindObject.OldRotation;
+ // //_globalCentroid = _bindObject.OldPosition;
+ // _impluses.Sort((a, b) =>
+ // {
+ // return a.Time.CompareTo(b.Time);
+ // });
+ // float lastTime = 0;
+ // int sameTimeCount = 0;
+ // for (int i = 0; i < _impluses.Count; i++)
+ // {
+ // sameTimeCount++;
+ // if (i == _impluses.Count - 1 || _impluses[i].Time != _impluses[i + 1].Time)
+ // {
+ // float dt = (_impluses[i].Time - lastTime);
+
+ // Vector2 linearVelocityChange = Vector2.Zero;
+ // float angularVelocityChange = 0;
+ // Vector2 normalAvg = Vector2.Zero;
+
+ // //linearVelocityChange /= sameTimeCount;
+ // //angularVelocityChange /= sameTimeCount;
+ // //normalAvg /= sameTimeCount;
+ // //normalAvg = normalAvg.SafeNormalize(Vector2.Zero);
+
+
+
+ // var resImpluses = ResolveConstrains();
+ // for (int j = i - sameTimeCount + 1; j <= i; j++)
+ // {
+ // linearVelocityChange += 1.0f / _mass * resImpluses[j] * _impluses[j].Normal;
+ // angularVelocityChange += (float)(Utils.Cross(_impluses[j].RelativePosition,
+ // resImpluses[j] *_impluses[j].Normal * (float)_globalInverseInertiaTensor));
+ // }
+
+
+ // //var penetration = Math.Max(0, -Vector2.Dot(_linearVelocity * deltaTime, normalAvg));
+ // //_linearVelocity += normalAvg * penetration * 0.7f;
+
+ // deltaTime -= dt;
+ // lastTime = _impluses[i].Time;
+ // sameTimeCount = 0;
+ // }
+ // }
+ // _impluses.Clear();
+ //}
+
+ //private List ResolveConstrains()
+ //{
+ // List impluseArray = new List();
+ // List impluseArrayTemp = new List();
+ // for (int k = 0; k < _impluses.Count; k++)
+ // {
+ // impluseArray.Add(_impluses[k].Impluse.Length());
+ // impluseArrayTemp.Add(0f);
+ // }
+ // for (int iter = 0; iter < 8; iter++)
+ // {
+ // int sameSourceCount = 0;
+ // for (int k = 0; k < _impluses.Count; k++)
+ // {
+ // var ri0 = _impluses[k].CollisionEvent.LocalOffsetSrc;
+ // var rb0 = _impluses[k].CollisionEvent.LocalOffsetTarget;
+ // var n0 = _impluses[k].CollisionEvent.Normal;
+ // var va0 = _impluses[k].CollisionEvent.Source.RigidBody.LinearVelocity
+ // + Utils.AnuglarVelocityToLinearVelocity(ri0, _impluses[k].CollisionEvent.Source.RigidBody.AngularVelocity);
+ // var vb0 = _impluses[k].CollisionEvent.Target.RigidBody.LinearVelocity
+ // + Utils.AnuglarVelocityToLinearVelocity(rb0, _impluses[k].CollisionEvent.Target.RigidBody.AngularVelocity);
+ // float relv0_n = Vector2.Dot(va0 - vb0, n0);
+ // float relv0_plus = -(1 + 0.4f) * Vector2.Dot(va0 - vb0, n0);
+
+ // float Kj = _impluses[k].CollisionEvent.Source.RigidBody.InvMass + _impluses[k].CollisionEvent.Target.RigidBody.InvMass
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0, (float)(_impluses[k].CollisionEvent.Source.RigidBody.GlobalInverseInertiaTensor
+ // * Utils.Cross(ri0, n0))), n0)
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb0, (float)(_impluses[k].CollisionEvent.Target.RigidBody.GlobalInverseInertiaTensor
+ // * Utils.Cross(rb0, n0))), n0);
+
+ // float KLU = 0f;
+ // for (int l = 0; l < _impluses.Count; l++)
+ // {
+ // if (l == k)
+ // {
+ // continue;
+ // }
+ // var ri1 = _impluses[l].CollisionEvent.LocalOffsetSrc;
+ // var rb1 = _impluses[l].CollisionEvent.LocalOffsetTarget;
+ // var n1 = _impluses[l].CollisionEvent.Normal;
+
+ // KLU += (_impluses[k].CollisionEvent.Source.RigidBody.InvMass
+ // * Vector2.Dot(n0, n1) + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0,
+ // (float)(_impluses[k].CollisionEvent.Source.RigidBody.GlobalInverseInertiaTensor
+ // * Utils.Cross(ri1, n1))), n0)) * impluseArray[l];
+ // }
+ // impluseArrayTemp[k] = 1 / Kj * (relv0_plus - KLU);
+ // }
+ // sameSourceCount = 0;
+ // // Deep copy
+ // for (int k = 0; k < impluseArray.Count; k++)
+ // {
+ // impluseArray[k] = impluseArrayTemp[k];
+ // }
+ // }
+
+ // return impluseArray;
+ //}
+
+ ///
+ /// 把冲量数据累加到这个刚体上
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void AddImpluse(Vector2 J, Vector2 relativePos, RigidBody2D other, Vector2 J2, Vector2 relativePos2)
+ {
+ var entry = new ImpluseEntry()
+ {
+ Source = this,
+ Target = other,
+ ImpluseSource = J,
+ RelativePositionSource = relativePos,
+ ImpluseTarget = J2,
+ RelativePositionTarget = relativePos2
+ };
+ _impluses.Add(entry);
+ }
+
+ ///
+ /// 对累加的冲量进行应用,更新各种速度
+ ///
+ public void ApplyImpluses()
+ {
+ if (_impluses.Count > 0)
+ {
+ foreach (var imp in _impluses)
+ {
+ if (imp.Source.MovementType == MovementType.Dynamic || imp.Source.MovementType == MovementType.Player)
+ {
+ _linearVelocity += 1.0f / _mass * imp.ImpluseSource;
+ if (imp.Source.MovementType != MovementType.Player)
+ {
+ _angularVelocity += GeometryUtils.Cross(imp.RelativePositionSource, imp.ImpluseSource * (float)_globalInverseInertiaTensor);
+ }
+ }
+ if (imp.Target.MovementType == MovementType.Dynamic || imp.Target.MovementType == MovementType.Player)
+ {
+ imp.Target._linearVelocity += imp.Target.InvMass * imp.ImpluseTarget;
+ if (imp.Target.MovementType != MovementType.Player)
+ {
+ imp.Target._angularVelocity += GeometryUtils.Cross(imp.RelativePositionTarget, imp.ImpluseTarget * (float)imp.Target.GlobalInverseInertiaTensor);
+ }
+ }
+
+ }
+ }
+ StabilizeBody();
+ _impluses.Clear();
+ }
+
+ ///
+ /// 立即施加一个冲量
+ ///
+ ///
+ ///
+ public void AddImpluseImmediate(Vector2 J, Vector2 relativePos)
+ {
+ _linearVelocity += 1.0f / _mass * J;
+ Debug.Assert(!float.IsNaN(_linearVelocity.X) && !float.IsNaN(_linearVelocity.Y));
+ _angularVelocity += (float)(GeometryUtils.Cross(relativePos,
+ J * (float)_globalInverseInertiaTensor));
+ Debug.Assert(!float.IsNaN(_angularVelocity));
+ }
+
+ public void MoveBody(Vector2 dir, float deltaTime)
+ {
+ _globalCentroid += dir;
+ // _linearVelocity = (_globalCentroid - ParentObject.OldPosition) / deltaTime;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Shaders/Default.fx b/Sources/Everglow.Core/Physics/PBEngine/Shaders/Default.fx
new file mode 100644
index 000000000..02c1e1446
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Shaders/Default.fx
@@ -0,0 +1,43 @@
+sampler uImage0 : register(s0);
+
+float4x4 uTransform;
+float uTime;
+
+struct VSInput
+{
+ float2 Pos : POSITION0;
+ float4 Color : COLOR0;
+ float2 Texcoord : TEXCOORD0;
+};
+
+struct PSInput
+{
+ float4 Pos : SV_POSITION;
+ float4 Color : COLOR0;
+ float2 Texcoord : TEXCOORD0;
+};
+
+
+PSInput VertexShaderFunction(VSInput input)
+{
+ PSInput output;
+ output.Color = input.Color;
+ output.Texcoord = input.Texcoord;
+ output.Pos = mul(float4(input.Pos, 0, 1), uTransform);
+ return output;
+}
+
+
+float4 PixelShaderFunction(PSInput input) : COLOR0
+{
+ return tex2D(uImage0, input.Texcoord) * input.Color;
+}
+
+technique Technique1
+{
+ pass Test
+ {
+ VertexShader = compile vs_3_0 VertexShaderFunction();
+ PixelShader = compile ps_3_0 PixelShaderFunction();
+ }
+}
\ No newline at end of file
diff --git a/Sources/Everglow.Core/Utilities/Matrix2x2.cs b/Sources/Everglow.Core/Utilities/Matrix2x2.cs
new file mode 100644
index 000000000..5ed29f298
--- /dev/null
+++ b/Sources/Everglow.Core/Utilities/Matrix2x2.cs
@@ -0,0 +1,210 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Utilities
+{
+ ///
+ /// 2x2 矩阵类
+ ///
+ public class Matrix2x2
+ {
+ public static Matrix2x2 Identity = new Matrix2x2(
+ new double[2, 2]
+ {
+ { 1, 0}, { 0, 1 },
+ });
+ public static Matrix2x2 Zero = new Matrix2x2(
+ new double[2, 2]
+ {
+ { 0, 0 }, { 0, 0 },
+ });
+
+ private double[,] _matrix;
+
+ public Matrix2x2()
+ {
+ _matrix = new double[2, 2];
+ }
+
+ public Matrix2x2(double[,] initialMatrix)
+ {
+ if (initialMatrix.GetLength(0) != 2 || initialMatrix.GetLength(1) != 2)
+ throw new ArgumentException("Initial matrix must be 2x2");
+
+ _matrix = initialMatrix;
+ }
+
+ public double this[int row, int col]
+ {
+ get
+ {
+ return _matrix[row, col];
+ }
+ set
+ {
+ _matrix[row, col] = value;
+ }
+ }
+
+ public double Trace()
+ {
+ return _matrix[0, 0] + _matrix[1, 1];
+ }
+
+ public Matrix2x2 Inverse()
+ {
+ double det = Determinant();
+ if (det == 0)
+ throw new InvalidOperationException("Matrix is not invertible.");
+
+ var result = new Matrix2x2
+ {
+ [0, 0] = _matrix[1, 1] / det,
+ [0, 1] = -_matrix[0, 1] / det,
+ [1, 0] = -_matrix[1, 0] / det,
+ [1, 1] = _matrix[0, 0] / det
+ };
+
+ return result;
+ }
+
+ public Matrix2x2 Multiply(Matrix2x2 other)
+ {
+ var result = new Matrix2x2
+ {
+ [0, 0] = this[0, 0] * other[0, 0] + this[0, 1] * other[1, 0],
+ [0, 1] = this[0, 0] * other[0, 1] + this[0, 1] * other[1, 1],
+ [1, 0] = this[1, 0] * other[0, 0] + this[1, 1] * other[1, 0],
+ [1, 1] = this[1, 0] * other[0, 1] + this[1, 1] * other[1, 1]
+ };
+
+ return result;
+ }
+
+ public Vector2 Multiply(Vector2 other)
+ {
+ return new Vector2((float)(this[0, 0] * other.X + this[0, 1] * other.Y),
+ (float)(this[1, 0] * other.X + this[1, 1] * other.Y));
+ }
+
+ public double Determinant()
+ {
+ return _matrix[0, 0] * _matrix[1, 1] - _matrix[0, 1] * _matrix[1, 0];
+ }
+
+ public Matrix2x2 Adjoint()
+ {
+ return new Matrix2x2
+ {
+ [0, 0] = _matrix[1, 1],
+ [0, 1] = -_matrix[0, 1],
+ [1, 0] = -_matrix[1, 0],
+ [1, 1] = _matrix[0, 0],
+ };
+ }
+
+ public static Matrix2x2 operator *(Matrix2x2 a, double b)
+ {
+ var result = new Matrix2x2
+ {
+ [0, 0] = a[0, 0] * b,
+ [0, 1] = a[0, 1] * b,
+ [1, 0] = a[1, 0] * b,
+ [1, 1] = a[1, 1] * b
+ };
+
+ return result;
+ }
+
+ public static Matrix2x2 operator *(double b, Matrix2x2 a)
+ {
+ var result = new Matrix2x2
+ {
+ [0, 0] = a[0, 0] * b,
+ [0, 1] = a[0, 1] * b,
+ [1, 0] = a[1, 0] * b,
+ [1, 1] = a[1, 1] * b
+ };
+
+ return result;
+ }
+
+ public static Matrix2x2 operator *(Matrix2x2 a, Matrix2x2 b)
+ {
+ var result = new Matrix2x2
+ {
+ [0, 0] = a[0, 0] * b[0, 0] + a[0, 1] * b[1, 0],
+ [0, 1] = a[0, 0] * b[0, 1] + a[0, 1] * b[1, 1],
+ [1, 0] = a[1, 0] * b[0, 0] + a[1, 1] * b[1, 0],
+ [1, 1] = a[1, 0] * b[0, 1] + a[1, 1] * b[1, 1]
+ };
+
+ return result;
+ }
+
+ public static Matrix2x2 operator +(Matrix2x2 a, Matrix2x2 b)
+ {
+ var result = new Matrix2x2
+ {
+ [0, 0] = a[0, 0] + b[0, 0],
+ [0, 1] = a[0, 1] + b[0, 1],
+ [1, 0] = a[1, 0] + b[1, 0],
+ [1, 1] = a[1, 1] + b[1, 1]
+ };
+
+ return result;
+ }
+
+ public static Matrix2x2 operator -(Matrix2x2 a, Matrix2x2 b)
+ {
+ var result = new Matrix2x2
+ {
+ [0, 0] = a[0, 0] - b[0, 0],
+ [0, 1] = a[0, 1] - b[0, 1],
+ [1, 0] = a[1, 0] - b[1, 0],
+ [1, 1] = a[1, 1] - b[1, 1]
+ };
+
+ return result;
+ }
+
+ public static Matrix2x2 operator /(Matrix2x2 a, Matrix2x2 b)
+ {
+ var result = new Matrix2x2
+ {
+ [0, 0] = a[0, 0] / b[0, 0],
+ [0, 1] = a[0, 1] / b[0, 1],
+ [1, 0] = a[1, 0] / b[1, 0],
+ [1, 1] = a[1, 1] / b[1, 1]
+ };
+
+ return result;
+ }
+
+ public Matrix2x2 Transpose()
+ {
+ return new Matrix2x2
+ {
+ [0, 0] = _matrix[0, 0],
+ [0, 1] = _matrix[1, 0],
+ [1, 0] = _matrix[0, 1],
+ [1, 1] = _matrix[1, 1],
+ };
+ }
+
+
+ public static Matrix2x2 CreateRotationMatrix(float r)
+ {
+ return new Matrix2x2
+ {
+ [0, 0] = Math.Cos(r),
+ [0, 1] = -Math.Sin(r),
+ [1, 0] = Math.Sin(r),
+ [1, 1] = Math.Cos(r),
+ };
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Utilities/Matrix3x3.cs b/Sources/Everglow.Core/Utilities/Matrix3x3.cs
new file mode 100644
index 000000000..6180665ee
--- /dev/null
+++ b/Sources/Everglow.Core/Utilities/Matrix3x3.cs
@@ -0,0 +1,217 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Everglow.Commons.Utilities
+{
+ public class Matrix3x3
+ {
+ public static Matrix3x3 Identity = new Matrix3x3(new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1));
+ private double[,] _matrix;
+
+ public Matrix3x3()
+ {
+ _matrix = new double[3, 3];
+ }
+ public Matrix3x3(double[,] initialMatrix)
+ {
+ if (initialMatrix.GetLength(0) != 3 || initialMatrix.GetLength(1) != 3)
+ throw new ArgumentException("Initial matrix must be 3x3");
+
+ _matrix = initialMatrix;
+ }
+
+ public double this[int row, int col]
+ {
+ get
+ {
+ return _matrix[row, col];
+ }
+ set
+ {
+ _matrix[row, col] = value;
+ }
+ }
+
+ public Matrix3x3(Vector3 col0, Vector3 col1, Vector3 col2)
+ {
+ _matrix = new double[3, 3];
+ _matrix[0, 0] = col0.X;
+ _matrix[1, 0] = col0.Y;
+ _matrix[2, 0] = col0.Z;
+
+ _matrix[0, 1] = col1.X;
+ _matrix[1, 1] = col1.Y;
+ _matrix[2, 1] = col1.Z;
+
+ _matrix[0, 2] = col2.X;
+ _matrix[1, 2] = col2.Y;
+ _matrix[2, 2] = col2.Z;
+ }
+
+ public static Matrix3x3 operator *(Matrix3x3 a, double x)
+ {
+ double[,] data = new double[3, 3];
+ for (int i = 0; i < 3; i++)
+ {
+ for (int j = 0; j < 3; j++)
+ {
+ data[i, j] = a._matrix[i, j] * x;
+ }
+ }
+
+ return new Matrix3x3(data);
+ }
+
+ public static Matrix3x3 operator -(Matrix3x3 a, Matrix3x3 b)
+ {
+ double[,] data = new double[3, 3];
+ for (int i = 0; i < 3; i++)
+ {
+ for (int j = 0; j < 3; j++)
+ {
+ data[i, j] = a._matrix[i, j] - b._matrix[i, j];
+ }
+ }
+
+ return new Matrix3x3(data);
+ }
+
+ public static Matrix3x3 operator +(Matrix3x3 a, Matrix3x3 b)
+ {
+ double[,] data = new double[3, 3];
+ for (int i = 0; i < 3; i++)
+ {
+ for (int j = 0; j < 3; j++)
+ {
+ data[i, j] = a._matrix[i, j] + b._matrix[i, j];
+ }
+ }
+
+ return new Matrix3x3(data);
+ }
+
+ public static Matrix3x3 operator /(Matrix3x3 a, Matrix3x3 b)
+ {
+ double[,] data = new double[3, 3];
+ for (int i = 0; i < 3; i++)
+ {
+ for (int j = 0; j < 3; j++)
+ {
+ data[i, j] = a._matrix[i, j] / b._matrix[i, j];
+ }
+ }
+
+ return new Matrix3x3(data);
+ }
+
+
+
+ public Matrix3x3 Transpose()
+ {
+ double[,] m = new double[3, 3];
+ m[0, 0] = _matrix[0, 0];
+ m[0, 1] = _matrix[1, 0];
+ m[0, 2] = _matrix[2, 0];
+
+ m[1, 0] = _matrix[0, 1];
+ m[1, 1] = _matrix[1, 1];
+ m[1, 2] = _matrix[2, 1];
+
+ m[2, 0] = _matrix[0, 2];
+ m[2, 1] = _matrix[1, 2];
+ m[2, 2] = _matrix[2, 2];
+ return new Matrix3x3(m);
+ }
+
+ public Matrix3x3 Multiply(Matrix3x3 other)
+ {
+ double[,] result = new double[3, 3];
+
+ result[0, 0] = _matrix[0, 0] * other._matrix[0, 0] + _matrix[0, 1] * other._matrix[1, 0] +
+ _matrix[0, 2] * other._matrix[2, 0];
+ result[0, 1] = _matrix[0, 0] * other._matrix[0, 1] + _matrix[0, 1] * other._matrix[1, 1] +
+ _matrix[0, 2] * other._matrix[2, 1];
+ result[0, 2] = _matrix[0, 0] * other._matrix[0, 2] + _matrix[0, 1] * other._matrix[1, 2] +
+ _matrix[0, 2] * other._matrix[2, 2];
+
+ result[1, 0] = _matrix[1, 0] * other._matrix[0, 0] + _matrix[1, 1] * other._matrix[1, 0] +
+ _matrix[1, 2] * other._matrix[2, 0];
+ result[1, 1] = _matrix[1, 0] * other._matrix[0, 1] + _matrix[1, 1] * other._matrix[1, 1] +
+ _matrix[1, 2] * other._matrix[2, 1];
+ result[1, 2] = _matrix[1, 0] * other._matrix[0, 2] + _matrix[1, 1] * other._matrix[1, 2] +
+ _matrix[1, 2] * other._matrix[2, 2];
+
+ result[2, 0] = _matrix[2, 0] * other._matrix[0, 0] + _matrix[2, 1] * other._matrix[1, 0] +
+ _matrix[2, 2] * other._matrix[2, 0];
+ result[2, 1] = _matrix[2, 0] * other._matrix[0, 1] + _matrix[2, 1] * other._matrix[1, 1] +
+ _matrix[2, 2] * other._matrix[2, 1];
+ result[2, 2] = _matrix[2, 0] * other._matrix[0, 2] + _matrix[2, 1] * other._matrix[1, 2] +
+ _matrix[2, 2] * other._matrix[2, 2];
+
+ return new Matrix3x3(result);
+ }
+
+ public Vector3 Multiply(Vector3 v)
+ {
+ return new Vector3((float)(_matrix[0, 0] * v.X + _matrix[0, 1] * v.Y + _matrix[0, 2] * v.Z),
+ (float)(_matrix[1, 0] * v.X + _matrix[1, 1] * v.Y + _matrix[1, 2] * v.Z),
+ (float)(_matrix[2, 0] * v.X + _matrix[2, 1] * v.Y + _matrix[2, 2] * v.Z));
+ }
+
+ public double Determinant()
+ {
+ return _matrix[0, 0] * (_matrix[1, 1] * _matrix[2, 2] - _matrix[1, 2] * _matrix[2, 1]) -
+ _matrix[0, 1] * (_matrix[1, 0] * _matrix[2, 2] - _matrix[1, 2] * _matrix[2, 0]) +
+ _matrix[0, 2] * (_matrix[1, 0] * _matrix[2, 1] - _matrix[1, 1] * _matrix[2, 0]);
+ }
+
+ public Matrix3x3 Inverse()
+ {
+ double det = Determinant();
+ if (Math.Abs(det) < 1e-7)
+ throw new InvalidOperationException("Non-invertible matrix");
+
+ double[,] result = new double[3, 3];
+
+ result[0, 0] = (_matrix[1, 1] * _matrix[2, 2] - _matrix[1, 2] * _matrix[2, 1]) / det;
+ result[0, 1] = (_matrix[0, 2] * _matrix[2, 1] - _matrix[0, 1] * _matrix[2, 2]) / det;
+ result[0, 2] = (_matrix[0, 1] * _matrix[1, 2] - _matrix[0, 2] * _matrix[1, 1]) / det;
+ result[1, 0] = (_matrix[1, 2] * _matrix[2, 0] - _matrix[1, 0] * _matrix[2, 2]) / det;
+ result[1, 1] = (_matrix[0, 0] * _matrix[2, 2] - _matrix[0, 2] * _matrix[2, 0]) / det;
+ result[1, 2] = (_matrix[0, 2] * _matrix[1, 0] - _matrix[0, 0] * _matrix[1, 2]) / det;
+ result[2, 0] = (_matrix[1, 0] * _matrix[2, 1] - _matrix[1, 1] * _matrix[2, 0]) / det;
+ result[2, 1] = (_matrix[0, 1] * _matrix[2, 0] - _matrix[0, 0] * _matrix[2, 1]) / det;
+ result[2, 2] = (_matrix[0, 0] * _matrix[1, 1] - _matrix[0, 1] * _matrix[1, 0]) / det;
+
+ return new Matrix3x3(result);
+ }
+
+ public double Trace()
+ {
+ return _matrix[0, 0] + _matrix[1, 1] + _matrix[2, 2];
+ }
+
+ public Vector3 Column(int i)
+ {
+ return new Vector3((float)_matrix[0, i], (float)_matrix[1, i], (float)_matrix[2, i]);
+ }
+
+ public bool HasNaN()
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ for (int j = 0; j < 3; j++)
+ {
+ if (double.IsNaN(_matrix[i, j]))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Utilities/Utils.md b/Sources/Everglow.Core/Utilities/Utils.md
index 94a6b96c1..aa5fb7c4c 100644
--- a/Sources/Everglow.Core/Utilities/Utils.md
+++ b/Sources/Everglow.Core/Utilities/Utils.md
@@ -10,4 +10,10 @@
XNAһЩĽһװչ
## CSUtils
-SystemһЩİװչһ鷳ķʲôģ
\ No newline at end of file
+SystemһЩİװչһ鷳ķʲôģ
+
+## Matrix2x2
+2x2ʵֳ֣֧þתá桢תȵ
+
+## Matrix3x3
+2x2ʵֳ֣֧þתá桢תȵ
diff --git a/Sources/Modules/Example/RigidBodyDisplay.cs b/Sources/Modules/Example/RigidBodyDisplay.cs
new file mode 100644
index 000000000..fc86db526
--- /dev/null
+++ b/Sources/Modules/Example/RigidBodyDisplay.cs
@@ -0,0 +1,97 @@
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using Everglow.Commons.Physics.PBEngine.PlayGround.Constrain;
+using Everglow.Commons.Physics.PBEngine.PlayGround.Contact;
+using Everglow.Commons.Vertex;
+using ReLogic.Content;
+using ReLogic.Graphics;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria;
+using Terraria.GameContent;
+
+namespace Everglow.Commons.Physics.PBEngine
+{
+ internal class RigidBodyDisplay
+ {
+ private PhysicsSimulation _physicsSimulation;
+ private RenderTarget2D _canvasTarget;
+ private Asset _renderShader;
+
+ public static RigidBodyDisplay Instance;
+
+ public RigidBodyDisplay()
+ {
+ Instance = this;
+ }
+
+ private const int CANVAS_SIZE = 1024;
+
+ public void Update()
+ {
+ _physicsSimulation.Update(0.1f);
+ }
+
+ public void Draw(SpriteBatch sb)
+ {
+ GeometryUtils.Blit(Main.screenTarget, Main.screenTargetSwap, null, null);
+ RenderPhysWorld();
+ GeometryUtils.Blit(Main.screenTargetSwap, Main.screenTarget, null, null);
+ sb.Begin();
+ var start = Main.LocalPlayer.Center - new Vector2(CANVAS_SIZE / 2, CANVAS_SIZE / 2) - Main.screenPosition;
+ sb.Draw(TextureAssets.MagicPixel.Value, new Rectangle((int)start.X - 2, (int)start.Y - 2, CANVAS_SIZE + 4, CANVAS_SIZE + 4), Color.White);
+ sb.Draw(_canvasTarget, Main.LocalPlayer.Center - new Vector2(CANVAS_SIZE / 2, CANVAS_SIZE / 2) - Main.screenPosition,
+ null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.FlipVertically, 0f);
+
+ sb.DrawString(FontAssets.MouseText.Value, "[Profiler]", start, Color.Green);
+ sb.DrawString(FontAssets.MouseText.Value, $"PreIntegration Time: {_physicsSimulation.MeasuredPreIntegrationTimeInMs} ms", start + new Vector2(0, 28), Color.Green);
+ sb.DrawString(FontAssets.MouseText.Value, $"BroadPhase Time: {_physicsSimulation.MeasuredBroadPhaseTimeInMs} ms", start + new Vector2(0, 56), Color.Green);
+ sb.DrawString(FontAssets.MouseText.Value, $"NarrowPhase Time: {_physicsSimulation.MeasuredNarrowPhaseTimeInMs} ms", start + new Vector2(0, 74), Color.Green);
+
+ sb.End();
+ }
+
+ private void RenderPhysWorld()
+ {
+ List vertices = new List();
+
+ foreach (var p in _physicsSimulation.GetCurrentWireFrames())
+ {
+ vertices.Add(new Vertex2D(p, Color.White, Vector3.Zero));
+ }
+
+ Main.graphics.GraphicsDevice.SetRenderTarget(_canvasTarget);
+ Main.graphics.GraphicsDevice.Clear(Color.Black);
+ _renderShader.Value.Parameters["uTransform"].SetValue(Matrix.CreateOrthographicOffCenter(0f, CANVAS_SIZE, CANVAS_SIZE, 0f, 0f, 1f));
+ _renderShader.Value.CurrentTechnique.Passes[0].Apply();
+ Main.graphics.GraphicsDevice.Textures[0] = TextureAssets.MagicPixel.Value;
+ Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineList, vertices.ToArray(), 0, vertices.Count / 2);
+ }
+
+ public void ReInitPhysWorld()
+ {
+ _physicsSimulation = JointPlayground.SpringTriganluar();
+
+ //var staticPlane3 = new PhysicsObject(
+ // new AABBCollider(1, 40), null);
+ //staticPlane3.Position = new Vector2(200, 300);
+ //staticPlane3.Rotation = 0f;
+ //_physicsSimulation.AddPhysicsObject(staticPlane3);
+
+ _physicsSimulation.Initialize();
+ }
+
+ public void Initialize()
+ {
+ ReInitPhysWorld();
+ Main.QueueMainThreadAction(() =>
+ {
+ _canvasTarget = new RenderTarget2D(Main.graphics.GraphicsDevice, 1024, 1024);
+ });
+ _renderShader = ModContent.Request("ChatGPT/Core/Physics/Shaders/Default");
+ }
+ }
+}
From a900489b04c16c33b6df480878d839746e7ef42a Mon Sep 17 00:00:00 2001
From: CXUtk <2237367067@qq.com>
Date: Fri, 30 Jun 2023 17:15:11 -0700
Subject: [PATCH 02/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=BA=9B?=
=?UTF-8?q?=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...25\346\223\216\346\226\207\346\241\243.md" | 14 ++
.../Modules/Example/Everglow.Example.csproj | 3 +
Sources/Modules/Example/PhysicsDemo.cs | 211 ++++++++++++++++++
.../Example/VFX}/Default.fx | 1 +
.../Example/\346\226\207\346\241\243.md" | 2 +
5 files changed, 231 insertions(+)
create mode 100644 "Sources/Everglow.Core/Physics/PBEngine/\347\211\251\347\220\206\345\274\225\346\223\216\346\226\207\346\241\243.md"
create mode 100644 Sources/Modules/Example/PhysicsDemo.cs
rename Sources/{Everglow.Core/Physics/PBEngine/Shaders => Modules/Example/VFX}/Default.fx (97%)
create mode 100644 "Sources/Modules/Example/\346\226\207\346\241\243.md"
diff --git "a/Sources/Everglow.Core/Physics/PBEngine/\347\211\251\347\220\206\345\274\225\346\223\216\346\226\207\346\241\243.md" "b/Sources/Everglow.Core/Physics/PBEngine/\347\211\251\347\220\206\345\274\225\346\223\216\346\226\207\346\241\243.md"
new file mode 100644
index 000000000..d518a714f
--- /dev/null
+++ "b/Sources/Everglow.Core/Physics/PBEngine/\347\211\251\347\220\206\345\274\225\346\223\216\346\226\207\346\241\243.md"
@@ -0,0 +1,14 @@
+# PBEngine
+
+## չ
+мҪϵң
+[ ] Һ彻ٵӰԭ˶
+[ ] Marching Cubes߱㷨ػתײ
+[ ] εʷֺЧײ
+[ ] õŻԼ˳ﵽٶ
+[ ] ԼؽڡƵ
+[ ] Ӵij
+[ ] ײ
+[ ] ּŻм
+[ ] Զ߹
+[ ] ײԷֹ쳣
diff --git a/Sources/Modules/Example/Everglow.Example.csproj b/Sources/Modules/Example/Everglow.Example.csproj
index ba938f7b3..3eb1642e0 100644
--- a/Sources/Modules/Example/Everglow.Example.csproj
+++ b/Sources/Modules/Example/Everglow.Example.csproj
@@ -1,3 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/Sources/Modules/Example/PhysicsDemo.cs b/Sources/Modules/Example/PhysicsDemo.cs
new file mode 100644
index 000000000..b0b54c1e2
--- /dev/null
+++ b/Sources/Modules/Example/PhysicsDemo.cs
@@ -0,0 +1,211 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using Everglow.Commons.Physics.PBEngine;
+using Everglow.Commons.Vertex;
+using ReLogic.Content;
+using Terraria.GameContent;
+using Microsoft.Xna.Framework.Input;
+using Everglow.Commons.Physics.PBEngine.Collision.BroadPhase;
+using Everglow.Commons.Physics.PBEngine.GameInteraction;
+using Everglow.Commons.Physics.PBEngine.Collision;
+
+namespace Everglow.Example;
+
+internal class PhysicsPlayer : ModPlayer
+{
+ private PhysicsObject _movingPanel;
+ private Vector2 _prevPos;
+ private Vector2 _saveVelocity;
+ public override void OnEnterWorld()
+ {
+ }
+ public override void PostUpdate()
+ {
+ Main.LocalPlayer.velocity = _saveVelocity;
+ }
+
+ public override void PreUpdateMovement()
+ {
+ _prevPos = Main.LocalPlayer.Center;
+ float dt = 0.1f;
+ var oldPos = Main.LocalPlayer.Center;
+ var preVelY = Main.LocalPlayer.velocity.Y;
+ PhysicsDemo.Instance._dummyPlayer.RigidBody.LinearVelocity = GeometryUtils.ConvertToPhysicsSpace(Main.LocalPlayer.velocity / dt);
+ PhysicsDemo.Instance._dummyPlayer.Position = GeometryUtils.ConvertToPhysicsSpace(_prevPos);
+ PhysicsDemo.Instance._realSimulation.Update(dt);
+
+ // Main.LocalPlayer.Center = Physics.Utils.ConvertToPhysicsSpace(Display.Instance._dummyPlayer.Position);
+ Main.LocalPlayer.velocity = GeometryUtils.ConvertToPhysicsSpace(PhysicsDemo.Instance._dummyPlayer.RigidBody.LinearVelocity * dt);
+ _saveVelocity = Main.LocalPlayer.velocity;
+ if (preVelY > 0 && Math.Abs(Main.LocalPlayer.velocity.Y) < 0.01f)
+ {
+ Main.LocalPlayer.velocity.Y = 0;
+ }
+
+
+ if (_movingPanel != null)
+ {
+
+ if (Main.time % 1200 < 600)
+ {
+ _movingPanel.RigidBody.LinearVelocity = new Vector2(-3, 0);
+ }
+ else if (Main.time % 1200 >= 600)
+ {
+ _movingPanel.RigidBody.LinearVelocity = new Vector2(3, 0);
+ }
+ }
+
+ base.PreUpdateMovement();
+ }
+
+ public override void UpdateEquips()
+ {
+ base.UpdateEquips();
+ }
+ public override void SetControls()
+ {
+ base.SetControls();
+ if(Main.mouseLeft && Main.mouseLeftRelease)
+ {
+ var ball = new PhysicsObject(new SphereCollider(32),
+ new RigidBody2D(256));
+ PhysicsDemo.Instance._realSimulation.AddPhysicsObject(ball);
+ ball.Position = GeometryUtils.ConvertToPhysicsSpace(Main.MouseWorld);
+ ball.RigidBody.LinearVelocity = new Vector2(0, 0);
+ }
+ if (Main.keyState[Keys.R] == KeyState.Down && Main.oldKeyState[Keys.R] == KeyState.Up)
+ {
+ // RigidBodyDisplay.Instance.ReInitPhysWorld();
+ PhysicsDemo.Instance.ReStart();
+ }
+
+ if (Main.keyState[Keys.T] == KeyState.Down && Main.oldKeyState[Keys.T] == KeyState.Up)
+ {
+ var dynamicBox = new PhysicsObject(
+ new BoxCollider(256, 64), new RigidBody2D(10233));
+ dynamicBox.Position = GeometryUtils.ConvertToPhysicsSpace(Main.LocalPlayer.Center - new Vector2(0, 200));
+ dynamicBox.Rotation = 0.0f;
+ dynamicBox.RigidBody.MovementType = MovementType.Kinematic;
+ dynamicBox.RigidBody.UseGravity = false;
+ PhysicsDemo.Instance._realSimulation.AddPhysicsObject(dynamicBox);
+ _movingPanel = dynamicBox;
+
+ //var ball = new PhysicsObject(new BoxCollider(32, 32),
+ // new RigidBody2D(256));
+ //Display.Instance._realSimulation.AddPhysicsObject(ball);
+ //ball.Position = Physics.Utils.ConvertToPhysicsSpace(Main.LocalPlayer.Center + new Vector2(0, -300));
+
+ var staticPlane1 = new PhysicsObject(
+ new BoxCollider(300, 32), null);
+ staticPlane1.Position = GeometryUtils.ConvertToPhysicsSpace(Main.LocalPlayer.Center - new Vector2(0, 400));
+ staticPlane1.Rotation = 0.4f;
+ PhysicsDemo.Instance._realSimulation.AddPhysicsObject(staticPlane1);
+
+ //var joint = new Spring(staticPlane1, dynamicBox, 40f, 200f, new Vector2(100, 0), new Vector2(100, 0));
+ //Display.Instance._realSimulation.AddConstrain(joint);
+
+ //var joint1 = new Spring(staticPlane1, dynamicBox, 40f, 200f, new Vector2(-100, 0), new Vector2(-100, 0));
+ //Display.Instance._realSimulation.AddConstrain(joint1);
+
+ //if (Main.rand.NextBool(2))
+ //{
+ // var ball = new PhysicsObject(new BoxCollider(256, 32),
+ // new RigidBody2D(128));
+ // ball.RigidBody.MovementType = Physics.Collision.MovementType.Kinematic;
+ // ball.RigidBody.UseGravity = false;
+ // ball.RigidBody.AngularDrag = 0;
+ // ball.RigidBody.AngularVelocity = 0.9f;
+ // Display.Instance._realSimulation.AddPhysicsObject(ball);
+ // ball.Position = Physics.Utils.ConvertToPhysicsSpace(Main.LocalPlayer.Center + new Vector2(0, -100));
+ //}
+ //else
+ //{
+ // var ball = new PhysicsObject(new SphereCollider(32),
+ // new RigidBody2D(256));
+ // Display.Instance._realSimulation.AddPhysicsObject(ball);
+ // ball.Position = Physics.Utils.ConvertToPhysicsSpace(Main.LocalPlayer.Center + new Vector2(100, 0));
+ // ball.RigidBody.LinearVelocity = new Vector2(-78, 0);
+ //}
+ }
+ }
+}
+
+internal class PhysicsDemo : ModSystem
+{
+ private RigidBodyDisplay rigidBodyDisplay;
+ private Asset _renderShader;
+ public PhysicsSimulation _realSimulation;
+ public static PhysicsDemo Instance;
+ public PhysicsObject _dummyPlayer;
+
+ public override void PostUpdateEverything()
+ {
+ //rigidBodyDisplay.Update();
+ }
+ public override void PostDrawTiles()
+ {
+ //rigidBodyDisplay.Draw(Main.spriteBatch);
+
+ List vertices = new List();
+ foreach (var p in _realSimulation.GetCurrentWireFrames())
+ {
+ vertices.Add(new Vertex2D(GeometryUtils.ConvertToPhysicsSpace(p) - Main.screenPosition, Color.White, Vector3.Zero));
+ }
+
+ if (vertices.Count > 0)
+ {
+ _renderShader.Value.Parameters["uColor"].SetValue(Color.White.ToVector4());
+ _renderShader.Value.Parameters["uTransform"].SetValue(Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1));
+ _renderShader.Value.CurrentTechnique.Passes[0].Apply();
+ Main.graphics.GraphicsDevice.Textures[0] = TextureAssets.MagicPixel.Value;
+ Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineList, vertices.ToArray(), 0, vertices.Count / 2);
+ }
+ base.PostDrawTiles();
+ }
+
+ public override void Load()
+ {
+ //rigidBodyDisplay = new RigidBodyDisplay();
+ //rigidBodyDisplay.Initialize();
+
+ Instance = this;
+ ReStart();
+ _renderShader = ModContent.Request("Everglow/Example/VFX/PureColor");
+ base.Load();
+ }
+
+ public void ReStart()
+ {
+ var terrariaCollisionGroup = new CollisionGraph();
+ _realSimulation = new PhysicsSimulation(terrariaCollisionGroup);
+ terrariaCollisionGroup.AddSingleEdge("Default", "Terrain");
+ terrariaCollisionGroup.AddDoubleEdge("Player", "Default");
+
+ var terrain = new PhysicsObject(new TileCollider(), null);
+ _realSimulation.AddPhysicsObject(terrain);
+ terrain.Tag = "Terrain";
+ terrain.RigidBody.MovementType = MovementType.Static;
+
+ var rigidb = new RigidBody2D(64);
+ _dummyPlayer = new PhysicsObject(new BoxCollider(20, 42), rigidb);
+ _dummyPlayer.Tag = "Player";
+ rigidb.MovementType = MovementType.Player;
+ rigidb.UseGravity = false;
+ rigidb.AngularDrag = 0;
+ rigidb.Drag = 0;
+ rigidb.Stiffness = -1;
+ rigidb.Friction = -1;
+ _realSimulation.AddPhysicsObject(_dummyPlayer);
+ _realSimulation.Initialize();
+ }
+
+ public override void Unload()
+ {
+ base.Unload();
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Shaders/Default.fx b/Sources/Modules/Example/VFX/Default.fx
similarity index 97%
rename from Sources/Everglow.Core/Physics/PBEngine/Shaders/Default.fx
rename to Sources/Modules/Example/VFX/Default.fx
index 02c1e1446..406382297 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/Shaders/Default.fx
+++ b/Sources/Modules/Example/VFX/Default.fx
@@ -1,3 +1,4 @@
+// ߿Ļ
sampler uImage0 : register(s0);
float4x4 uTransform;
diff --git "a/Sources/Modules/Example/\346\226\207\346\241\243.md" "b/Sources/Modules/Example/\346\226\207\346\241\243.md"
new file mode 100644
index 000000000..7188c2a67
--- /dev/null
+++ "b/Sources/Modules/Example/\346\226\207\346\241\243.md"
@@ -0,0 +1,2 @@
+# Գ˵
+ԳļڿʱЧIJԣڷǰְDemoļע͵
From a62701849b03e3c374a3cda8d1ad4e23c083c8e7 Mon Sep 17 00:00:00 2001
From: CXUtk <2237367067@qq.com>
Date: Fri, 30 Jun 2023 23:05:29 -0700
Subject: [PATCH 03/13] spring fix
---
.../PBEngine/Constrains/SpringConstrain.cs | 81 ++++++++++++++-----
.../Physics/PBEngine/PhysicsSimulation.cs | 10 +--
.../Physics/PBEngine/RigidBody2D.cs | 6 ++
Sources/Modules/Example/PhysicsDemo.cs | 36 ++++-----
4 files changed, 87 insertions(+), 46 deletions(-)
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs b/Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs
index ed2447b90..144620b7a 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/Constrains/SpringConstrain.cs
@@ -40,7 +40,25 @@ public SpringConstrain(PhysicsObject A, PhysicsObject B, float elasticity, float
_localPosB = localPosB;
}
- public override void Apply(float deltaTime)
+ public static double CalculateShortestAngleDifference(double angle1, double angle2)
+ {
+ double difference = angle2 - angle1;
+ difference = (difference + Math.PI) % (2 * Math.PI) - Math.PI;
+
+ // Adjust the difference to the shortest rotating radians
+ if (difference < -Math.PI)
+ {
+ difference += 2 * Math.PI;
+ }
+ else if (difference >= Math.PI)
+ {
+ difference -= 2 * Math.PI;
+ }
+
+ return difference;
+ }
+
+ public override void Apply(float deltaTime)
{
var pA = _objA.LocalToWorldPos(_localPosA);
var pB = _objB.LocalToWorldPos(_localPosB);
@@ -54,32 +72,51 @@ public override void Apply(float deltaTime)
var curPosA = pA + _lambda * _objA.RigidBody.InvMass * -unit;
var curPosB = pB + _lambda * _objB.RigidBody.InvMass * unit;
- var ra = Matrix2x2.CreateRotationMatrix(_objA.Rotation).Multiply(_localPosA);
- var rb = Matrix2x2.CreateRotationMatrix(_objB.Rotation).Multiply(_localPosB);
- var da = (_lambda * _objA.RigidBody.InvMass * -unit).SafeNormalize(Vector2.Zero);
- var db = (_lambda * _objB.RigidBody.InvMass * unit).SafeNormalize(Vector2.Zero);
- var oldVelA = Vector2.Dot(_objA.RigidBody.LinearVelocity + GeometryUtils.AnuglarVelocityToLinearVelocity(ra, _objA.RigidBody.AngularVelocity), da);
- var oldVelB = Vector2.Dot(_objB.RigidBody.LinearVelocity + GeometryUtils.AnuglarVelocityToLinearVelocity(rb, _objB.RigidBody.AngularVelocity), db);
-
- double rAdotN = Vector2.Dot(GeometryUtils.Rotate90(ra), da);
- double rBdotN = Vector2.Dot(GeometryUtils.Rotate90(rb), db);
- double R1 = rAdotN * rAdotN * _objA.RigidBody.GlobalInverseInertiaTensor;
- double R2 = rBdotN * rBdotN * _objB.RigidBody.GlobalInverseInertiaTensor;
- var impluseA = ((curPosA - pA).Length() / deltaTime - oldVelA) / (_objA.RigidBody.InvMass + (float)R1);
- var impluseB = ((curPosB - pB).Length() / deltaTime - oldVelB) / (_objB.RigidBody.InvMass + (float)R2);
-
- if (_objA.RigidBody.InvMass != 0)
+
+ _objB.RigidBody.AddForce(40 * (L - _restLength) * -unit, _localPosB);
+ //float rotB_p = (pB - _objB.RigidBody.CentroidWorldSpace).ToRotation() - _localPosB.ToRotation();
+ //float rotB = (curPosB - _objB.RigidBody.CentroidWorldSpace).ToRotation() - _localPosB.ToRotation();
+
+ //_objB.Rotation = rotB;
+
+ //_objB.RigidBody.CentroidWorldSpace += curPosB - _objB.LocalToWorldPos(_localPosB);
+ //_objB.RigidBody.LinearVelocity = (_objB.Position - _objB.OldPosition) / deltaTime;
+ //_objB.RigidBody.AngularVelocity = (float)CalculateShortestAngleDifference(_objB.OldRotation, _objB.Rotation) / deltaTime;
+
+ //var ra = Matrix2x2.CreateRotationMatrix(_objA.Rotation).Multiply(_localPosA);
+ //var rb = Matrix2x2.CreateRotationMatrix(_objB.Rotation).Multiply(_localPosB);
+ //var da = (_lambda * _objA.RigidBody.InvMass * -unit).SafeNormalize(Vector2.Zero);
+ //var db = (_lambda * _objB.RigidBody.InvMass * unit).SafeNormalize(Vector2.Zero);
+ //var oldVelA = Vector2.Dot(_objA.RigidBody.LinearVelocity + GeometryUtils.AnuglarVelocityToLinearVelocity(ra, _objA.RigidBody.AngularVelocity), da);
+ //var oldVelB = Vector2.Dot(_objB.RigidBody.LinearVelocity + GeometryUtils.AnuglarVelocityToLinearVelocity(rb, _objB.RigidBody.AngularVelocity), db);
+
+ //double rAdotN = Vector2.Dot(GeometryUtils.Rotate90(ra), da);
+ //double rBdotN = Vector2.Dot(GeometryUtils.Rotate90(rb), db);
+ //double R1 = rAdotN * rAdotN * _objA.RigidBody.GlobalInverseInertiaTensor;
+ //double R2 = rBdotN * rBdotN * _objB.RigidBody.GlobalInverseInertiaTensor;
+ //var impluseA = ((curPosA - pA).Length() / deltaTime - oldVelA) / (_objA.RigidBody.InvMass + (float)R1);
+ //var impluseB = ((curPosB - pB).Length() / deltaTime - oldVelB) / (_objB.RigidBody.InvMass + (float)R2);
+
+ if (_objA.RigidBody.InvMass != 0)
{
- _objA.RigidBody.AddImpluseImmediate(impluseA * da, ra);
+ // _objA.RigidBody.AddImpluseImmediate(impluseA * da, ra);
_objA.Position += _objA.RigidBody.LinearVelocity * deltaTime;
_objA.Rotation += _objA.RigidBody.AngularVelocity * deltaTime;
- }
+
+ _objA.RigidBody.LinearVelocity = (_objA.Position - _objA.OldPosition) / deltaTime;
+ }
if (_objB.RigidBody.InvMass != 0)
{
- _objB.RigidBody.AddImpluseImmediate(impluseB * db, rb);
- _objB.Position += _objB.RigidBody.LinearVelocity * deltaTime;
- _objB.Rotation += _objB.RigidBody.AngularVelocity * deltaTime;
- }
+ // _objB.RigidBody.AddImpluseImmediate(impluseB * db, rb);
+ //_objB.Position += _objB.RigidBody.LinearVelocity * deltaTime;
+ //_objB.Rotation += _objB.RigidBody.AngularVelocity * deltaTime;
+ //var test = _objB.LocalToWorldPos(_localPosB);
+ //if (true)
+ // ;
+
+ //_objB.RigidBody.LinearVelocity = (_objB.Position - _objB.OldPosition) / deltaTime;
+ //_objB.RigidBody.AngularVelocity = (_objB.Rotation - _objB.OldRotation) / deltaTime;
+ }
//_objA.RigidBody.AngularVelocity = Utils.Cross(_localPosA, _objA.RigidBody.LinearVelocity);
//_objB.RigidBody.AngularVelocity = Utils.Cross(_localPosB, _objB.RigidBody.LinearVelocity);
}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs b/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
index f29270279..5c7f800cc 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
@@ -160,7 +160,11 @@ public List GetCurrentWireFrames()
///
private void PreIntegration(float deltaTime)
{
- foreach (PhysicsObject pobj in _staticPhysObjects)
+ foreach (var joint in _constrains)
+ {
+ joint.Apply(deltaTime);
+ }
+ foreach (PhysicsObject pobj in _staticPhysObjects)
{
pobj.RecordOldState();
}
@@ -185,10 +189,6 @@ private void Resolve(float deltaTime, Stopwatch broadPhase, Stopwatch narrowPhas
broadPhase.Stop();
narrowPhase.Start();
- foreach (var joint in _constrains)
- {
- joint.Apply(deltaTime);
- }
foreach (var pair in pairs)
{
CollisionInfo info;
diff --git a/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs b/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
index 43e294f08..451ba9193 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
@@ -507,6 +507,12 @@ public void Integrate(float deltaTime)
// return impluseArray;
//}
+ public void AddForce(Vector2 force, Vector2 relPos)
+ {
+ _force += force;
+ _torque += GeometryUtils.Cross(relPos, force);
+ }
+
///
/// 把冲量数据累加到这个刚体上
///
diff --git a/Sources/Modules/Example/PhysicsDemo.cs b/Sources/Modules/Example/PhysicsDemo.cs
index b0b54c1e2..4738e910e 100644
--- a/Sources/Modules/Example/PhysicsDemo.cs
+++ b/Sources/Modules/Example/PhysicsDemo.cs
@@ -12,6 +12,7 @@
using Everglow.Commons.Physics.PBEngine.Collision.BroadPhase;
using Everglow.Commons.Physics.PBEngine.GameInteraction;
using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Constrains;
namespace Everglow.Example;
@@ -25,7 +26,6 @@ public override void OnEnterWorld()
}
public override void PostUpdate()
{
- Main.LocalPlayer.velocity = _saveVelocity;
}
public override void PreUpdateMovement()
@@ -40,8 +40,7 @@ public override void PreUpdateMovement()
// Main.LocalPlayer.Center = Physics.Utils.ConvertToPhysicsSpace(Display.Instance._dummyPlayer.Position);
Main.LocalPlayer.velocity = GeometryUtils.ConvertToPhysicsSpace(PhysicsDemo.Instance._dummyPlayer.RigidBody.LinearVelocity * dt);
- _saveVelocity = Main.LocalPlayer.velocity;
- if (preVelY > 0 && Math.Abs(Main.LocalPlayer.velocity.Y) < 0.01f)
+ if (preVelY > 0 && Math.Abs(Main.LocalPlayer.velocity.Y) < 0.04f)
{
Main.LocalPlayer.velocity.Y = 0;
}
@@ -50,14 +49,14 @@ public override void PreUpdateMovement()
if (_movingPanel != null)
{
- if (Main.time % 1200 < 600)
- {
- _movingPanel.RigidBody.LinearVelocity = new Vector2(-3, 0);
- }
- else if (Main.time % 1200 >= 600)
- {
- _movingPanel.RigidBody.LinearVelocity = new Vector2(3, 0);
- }
+ //if (Main.time % 1200 < 600)
+ //{
+ // _movingPanel.RigidBody.LinearVelocity = new Vector2(-3, 0);
+ //}
+ //else if (Main.time % 1200 >= 600)
+ //{
+ // _movingPanel.RigidBody.LinearVelocity = new Vector2(3, 0);
+ //}
}
base.PreUpdateMovement();
@@ -87,11 +86,10 @@ public override void SetControls()
if (Main.keyState[Keys.T] == KeyState.Down && Main.oldKeyState[Keys.T] == KeyState.Up)
{
var dynamicBox = new PhysicsObject(
- new BoxCollider(256, 64), new RigidBody2D(10233));
+ new BoxCollider(256, 64), new RigidBody2D(1000));
dynamicBox.Position = GeometryUtils.ConvertToPhysicsSpace(Main.LocalPlayer.Center - new Vector2(0, 200));
dynamicBox.Rotation = 0.0f;
- dynamicBox.RigidBody.MovementType = MovementType.Kinematic;
- dynamicBox.RigidBody.UseGravity = false;
+ dynamicBox.RigidBody.MovementType = MovementType.Dynamic;
PhysicsDemo.Instance._realSimulation.AddPhysicsObject(dynamicBox);
_movingPanel = dynamicBox;
@@ -103,14 +101,14 @@ public override void SetControls()
var staticPlane1 = new PhysicsObject(
new BoxCollider(300, 32), null);
staticPlane1.Position = GeometryUtils.ConvertToPhysicsSpace(Main.LocalPlayer.Center - new Vector2(0, 400));
- staticPlane1.Rotation = 0.4f;
+ staticPlane1.Rotation = 0.0f;
PhysicsDemo.Instance._realSimulation.AddPhysicsObject(staticPlane1);
- //var joint = new Spring(staticPlane1, dynamicBox, 40f, 200f, new Vector2(100, 0), new Vector2(100, 0));
- //Display.Instance._realSimulation.AddConstrain(joint);
+ var joint = new SpringConstrain(staticPlane1, dynamicBox, 40f, 200f, new Vector2(100, 0), new Vector2(100, 0));
+ PhysicsDemo.Instance._realSimulation.AddConstrain(joint);
- //var joint1 = new Spring(staticPlane1, dynamicBox, 40f, 200f, new Vector2(-100, 0), new Vector2(-100, 0));
- //Display.Instance._realSimulation.AddConstrain(joint1);
+ var joint1 = new SpringConstrain(staticPlane1, dynamicBox, 100f, 200f, new Vector2(-100, 0), new Vector2(-100, 0));
+ PhysicsDemo.Instance._realSimulation.AddConstrain(joint1);
//if (Main.rand.NextBool(2))
//{
From 4664e09910c3154001037ed8114a64ae72eb0360 Mon Sep 17 00:00:00 2001
From: CXUtk <2237367067@qq.com>
Date: Sat, 1 Jul 2023 00:28:56 -0700
Subject: [PATCH 04/13] inertia
---
.../Physics/PBEngine/PhysicsSimulation.cs | 5 +-
.../Physics/PBEngine/RigidBody2D.cs | 110 ++++++++++--------
Sources/Modules/Example/PhysicsDemo.cs | 52 ++++++---
3 files changed, 101 insertions(+), 66 deletions(-)
diff --git a/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs b/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
index 5c7f800cc..1c52c3027 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/PhysicsSimulation.cs
@@ -111,7 +111,8 @@ public void Initialize()
///
public void Update(float deltaTime)
{
- foreach (PhysicsObject pobj in _dynamicPhysObjects)
+ CleanThisFrame();
+ foreach (PhysicsObject pobj in _dynamicPhysObjects)
{
pobj.ApplyGravity(new Vector2(0, -_gravity));
}
@@ -128,7 +129,7 @@ public void Update(float deltaTime)
Resolve(dt, _stopwatchBroadPhase, _stopwatchNarrowPhase);
}
- CleanThisFrame();
+
}
public void CleanThisFrame()
diff --git a/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs b/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
index 451ba9193..559ce04f7 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/RigidBody2D.cs
@@ -130,6 +130,11 @@ public float Friction
set => _friction = value;
}
+ public Vector2 TangetRelativeVelocity
+ {
+ get => _tangentRelativeVelocity;
+ }
+
private double _localInverseInertiaTensor;
private double _globalInverseInertiaTensor;
@@ -146,6 +151,8 @@ public float Friction
private float _stiffness;
private float _friction;
+ private Vector2 _tangentRelativeVelocity;
+
private List _impluses;
private bool _isAwake;
@@ -165,7 +172,9 @@ public RigidBody2D(float mass)
_impluses = new List();
_stiffness = 0.5f;
_friction = 0.5f;
- }
+ _tangentRelativeVelocity = Vector2.Zero;
+
+ }
private void CalculateMassCentroidAndMoI()
@@ -243,55 +252,56 @@ public void CleanUp()
_linearVelocity *= 1 - _drag * _drag;
_angularVelocity *= 1 - _angularDrag * _angularDrag;
- }
+ _tangentRelativeVelocity = Vector2.Zero;
+ }
- //public void RespondToEvents(List events, float deltaTime)
- //{
- // var ri0 = events[0].LocalOffsetSrc;
- // var rb0 = events[0].LocalOffsetTarget;
- // var n0 = events[0].Normal;
- // var va0 = _linearVelocity + Utils.AnuglarVelocityToLinearVelocity(ri0, _angularVelocity);
- // var vb0 = events[0].Target.RigidBody._linearVelocity
- // + Utils.AnuglarVelocityToLinearVelocity(rb0, events[0].Target.RigidBody._angularVelocity);
- // float relv0_n = Vector2.Dot(va0 - vb0, n0);
-
- // var ri1 = events[1].LocalOffsetSrc;
- // var rb1 = events[1].LocalOffsetTarget;
- // var n1 = events[1].Normal;
- // var va1 = _linearVelocity + Utils.AnuglarVelocityToLinearVelocity(ri1, _angularVelocity);
- // var vb1 = events[1].Target.RigidBody._linearVelocity
- // + Utils.AnuglarVelocityToLinearVelocity(rb1, events[1].Target.RigidBody._angularVelocity);
- // float relv1_n = Vector2.Dot(va1 - vb1, n1);
- // Matrix2x2 matrix = new Matrix2x2()
- // {
- // [0, 0] = InvMass + events[0].Target.RigidBody.InvMass
- // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0, (float)(GlobalInverseInertiaTensor
- // * Utils.Cross(ri0, n0))), n0)
- // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb0, (float)(events[0].Target.RigidBody.GlobalInverseInertiaTensor
- // * Utils.Cross(rb0, n0))), n0),
- // [0, 1] = InvMass * Vector2.Dot(n0, n1) + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0, (float)(GlobalInverseInertiaTensor
- // * Utils.Cross(ri1, n1))), n0),
-
- // [1, 0] = InvMass * Vector2.Dot(n0, n1) + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri1, (float)(GlobalInverseInertiaTensor
- // * Utils.Cross(ri0, n0))), n1),
- // [1, 1] = InvMass + events[1].Target.RigidBody.InvMass
- // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri1, (float)(GlobalInverseInertiaTensor
- // * Utils.Cross(ri1, n1))), n1)
- // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb1, (float)(events[1].Target.RigidBody.GlobalInverseInertiaTensor
- // * Utils.Cross(rb1, n1))), n1),
- // };
- // float C = 0.4f;
- // var J = matrix.Inverse().Multiply(new Vector2(-(1 + C) * relv0_n, -(1 + C) * relv1_n));
- // if (!J.HasNaNs())
- // {
- // AddImpluse(J.X * events[0].Normal, ri0, events[0].Time, events[0].Normal);
- // AddImpluse(J.Y * events[1].Normal, ri1, events[1].Time, events[1].Normal);
- // }
- // var t = matrix.Multiply(J);
- // if (true)
- // ;
- //}
- public void ApplyAngularVelocity(float w)
+ //public void RespondToEvents(List events, float deltaTime)
+ //{
+ // var ri0 = events[0].LocalOffsetSrc;
+ // var rb0 = events[0].LocalOffsetTarget;
+ // var n0 = events[0].Normal;
+ // var va0 = _linearVelocity + Utils.AnuglarVelocityToLinearVelocity(ri0, _angularVelocity);
+ // var vb0 = events[0].Target.RigidBody._linearVelocity
+ // + Utils.AnuglarVelocityToLinearVelocity(rb0, events[0].Target.RigidBody._angularVelocity);
+ // float relv0_n = Vector2.Dot(va0 - vb0, n0);
+
+ // var ri1 = events[1].LocalOffsetSrc;
+ // var rb1 = events[1].LocalOffsetTarget;
+ // var n1 = events[1].Normal;
+ // var va1 = _linearVelocity + Utils.AnuglarVelocityToLinearVelocity(ri1, _angularVelocity);
+ // var vb1 = events[1].Target.RigidBody._linearVelocity
+ // + Utils.AnuglarVelocityToLinearVelocity(rb1, events[1].Target.RigidBody._angularVelocity);
+ // float relv1_n = Vector2.Dot(va1 - vb1, n1);
+ // Matrix2x2 matrix = new Matrix2x2()
+ // {
+ // [0, 0] = InvMass + events[0].Target.RigidBody.InvMass
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri0, n0))), n0)
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb0, (float)(events[0].Target.RigidBody.GlobalInverseInertiaTensor
+ // * Utils.Cross(rb0, n0))), n0),
+ // [0, 1] = InvMass * Vector2.Dot(n0, n1) + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri0, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri1, n1))), n0),
+
+ // [1, 0] = InvMass * Vector2.Dot(n0, n1) + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri1, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri0, n0))), n1),
+ // [1, 1] = InvMass + events[1].Target.RigidBody.InvMass
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(ri1, (float)(GlobalInverseInertiaTensor
+ // * Utils.Cross(ri1, n1))), n1)
+ // + Vector2.Dot(Utils.AnuglarVelocityToLinearVelocity(rb1, (float)(events[1].Target.RigidBody.GlobalInverseInertiaTensor
+ // * Utils.Cross(rb1, n1))), n1),
+ // };
+ // float C = 0.4f;
+ // var J = matrix.Inverse().Multiply(new Vector2(-(1 + C) * relv0_n, -(1 + C) * relv1_n));
+ // if (!J.HasNaNs())
+ // {
+ // AddImpluse(J.X * events[0].Normal, ri0, events[0].Time, events[0].Normal);
+ // AddImpluse(J.Y * events[1].Normal, ri1, events[1].Time, events[1].Normal);
+ // }
+ // var t = matrix.Multiply(J);
+ // if (true)
+ // ;
+ //}
+ public void ApplyAngularVelocity(float w)
{
_angularVelocity += w;
}
@@ -348,6 +358,8 @@ private void SolveFrictionImpluse(CollisionEvent2D e, int count, float deltaTime
float vel_n = Vector2.Dot(va - vb, e.Normal);
Vector2 vt = (va - vb) - vel_n * e.Normal;
+ _tangentRelativeVelocity -= vb / count;
+ e.Target.RigidBody._tangentRelativeVelocity -= va / count;
float vel_t = vt.Length();
float friction = Math.Max(0, (_friction + e.Target.RigidBody.Friction) / 2);
diff --git a/Sources/Modules/Example/PhysicsDemo.cs b/Sources/Modules/Example/PhysicsDemo.cs
index 4738e910e..3dcb32ff0 100644
--- a/Sources/Modules/Example/PhysicsDemo.cs
+++ b/Sources/Modules/Example/PhysicsDemo.cs
@@ -20,16 +20,25 @@ internal class PhysicsPlayer : ModPlayer
{
private PhysicsObject _movingPanel;
private Vector2 _prevPos;
- private Vector2 _saveVelocity;
+ public Vector2 _extraVelocity;
public override void OnEnterWorld()
{
}
public override void PostUpdate()
{
+ Main.LocalPlayer.velocity += _extraVelocity;
+ _extraVelocity = PhysicsDemo.Instance._dummyPlayer.RigidBody.TangetRelativeVelocity * 0.1f;
+ _extraVelocity = Vector2.Dot(_extraVelocity, new Vector2(1, 0)) * new Vector2(1, 0);
+ }
+ public override void PreUpdate()
+ {
+
+ base.PreUpdate();
}
public override void PreUpdateMovement()
{
+ Main.LocalPlayer.velocity -= _extraVelocity;
_prevPos = Main.LocalPlayer.Center;
float dt = 0.1f;
var oldPos = Main.LocalPlayer.Center;
@@ -44,19 +53,19 @@ public override void PreUpdateMovement()
{
Main.LocalPlayer.velocity.Y = 0;
}
-
+ // Main.LocalPlayer.velocity -= _extraVelocity;
if (_movingPanel != null)
{
- //if (Main.time % 1200 < 600)
- //{
- // _movingPanel.RigidBody.LinearVelocity = new Vector2(-3, 0);
- //}
- //else if (Main.time % 1200 >= 600)
- //{
- // _movingPanel.RigidBody.LinearVelocity = new Vector2(3, 0);
- //}
+ if (Main.time % 1200 < 600)
+ {
+ _movingPanel.RigidBody.LinearVelocity = new Vector2(-3, 0);
+ }
+ else if (Main.time % 1200 >= 600)
+ {
+ _movingPanel.RigidBody.LinearVelocity = new Vector2(3, 0);
+ }
}
base.PreUpdateMovement();
@@ -89,7 +98,8 @@ public override void SetControls()
new BoxCollider(256, 64), new RigidBody2D(1000));
dynamicBox.Position = GeometryUtils.ConvertToPhysicsSpace(Main.LocalPlayer.Center - new Vector2(0, 200));
dynamicBox.Rotation = 0.0f;
- dynamicBox.RigidBody.MovementType = MovementType.Dynamic;
+ dynamicBox.RigidBody.MovementType = MovementType.Kinematic;
+ dynamicBox.RigidBody.UseGravity = false;
PhysicsDemo.Instance._realSimulation.AddPhysicsObject(dynamicBox);
_movingPanel = dynamicBox;
@@ -104,11 +114,11 @@ public override void SetControls()
staticPlane1.Rotation = 0.0f;
PhysicsDemo.Instance._realSimulation.AddPhysicsObject(staticPlane1);
- var joint = new SpringConstrain(staticPlane1, dynamicBox, 40f, 200f, new Vector2(100, 0), new Vector2(100, 0));
- PhysicsDemo.Instance._realSimulation.AddConstrain(joint);
+ //var joint = new SpringConstrain(staticPlane1, dynamicBox, 40f, 200f, new Vector2(100, 0), new Vector2(100, 0));
+ //PhysicsDemo.Instance._realSimulation.AddConstrain(joint);
- var joint1 = new SpringConstrain(staticPlane1, dynamicBox, 100f, 200f, new Vector2(-100, 0), new Vector2(-100, 0));
- PhysicsDemo.Instance._realSimulation.AddConstrain(joint1);
+ //var joint1 = new SpringConstrain(staticPlane1, dynamicBox, 100f, 200f, new Vector2(-100, 0), new Vector2(-100, 0));
+ //PhysicsDemo.Instance._realSimulation.AddConstrain(joint1);
//if (Main.rand.NextBool(2))
//{
@@ -145,6 +155,8 @@ public override void PostUpdateEverything()
{
//rigidBodyDisplay.Update();
}
+
+
public override void PostDrawTiles()
{
//rigidBodyDisplay.Draw(Main.spriteBatch);
@@ -174,9 +186,19 @@ public override void Load()
Instance = this;
ReStart();
_renderShader = ModContent.Request("Everglow/Example/VFX/PureColor");
+
+
+ On_Player.PlayerFrame += On_Player_PlayerFrame;
base.Load();
}
+ private void On_Player_PlayerFrame(On_Player.orig_PlayerFrame orig, Player self)
+ {
+ Main.LocalPlayer.velocity += self.GetModPlayer()._extraVelocity;
+ orig(self);
+ Main.LocalPlayer.velocity -= self.GetModPlayer()._extraVelocity;
+ }
+
public void ReStart()
{
var terrariaCollisionGroup = new CollisionGraph();
From e63903f47fbf79429986c0d1b6bbd325ad937270 Mon Sep 17 00:00:00 2001
From: CXUtk <2237367067@qq.com>
Date: Sat, 1 Jul 2023 09:59:24 -0700
Subject: [PATCH 05/13] Close other modules
---
Localization/en-US_Mods.Everglow.hjson | 2994 +----------------
Sources/Everglow/Module.Build.props | 3 +-
.../Modules/Example/Everglow.Example.csproj | 3 -
Sources/Modules/Example/PhysicsDemo.cs | 2 +-
4 files changed, 9 insertions(+), 2993 deletions(-)
diff --git a/Localization/en-US_Mods.Everglow.hjson b/Localization/en-US_Mods.Everglow.hjson
index efc8c0216..7d96a12ce 100644
--- a/Localization/en-US_Mods.Everglow.hjson
+++ b/Localization/en-US_Mods.Everglow.hjson
@@ -1,2926 +1,20 @@
-Tiles: {
- BottleOfNutShellFlowers.MapEntry: Bottle Of Nut Shell Flowers
- PlumBlossomInABowl.MapEntry: Plum Blossom In A Bowl
- WhiteLotusBonsai.MapEntry: White Lotus Bonsai
- BloodifyPlatform.MapEntry: Bloodify Platform
- BloodyMossWheel.MapEntry: Bloody Moss Wheel
- BloodyMossWheelFinished.MapEntry: Bloody Moss Wheel Finished
- StoneTusk.MapEntry: Stone Tusk
- StoneTuskSmall.MapEntry: Stone Tusk Small
- StrangeTuskStone.MapEntry: Strange Tusk Stone
- StrangeTuskStone1.MapEntry: Strange Tusk Stone1
- StrangeTuskStone2.MapEntry: Strange Tusk Stone2
- StrangeTuskStone3.MapEntry: Strange Tusk Stone3
- StrangeTuskStone4.MapEntry: Strange Tusk Stone4
- TuskRelic.MapEntry: Tusk Relic
- BlackFren.MapEntry: Black Fren
- BlackFrenLarge.MapEntry: Black Fren Large
- BlackStarShrub.MapEntry: Black Star Shrub
- BlackStarShrubSmall.MapEntry: Black Star Shrub Small
- BlackVine.MapEntry: Black Vine
- BlueBlossom.MapEntry: Blue Blossom
- CocoonRock.MapEntry: Cocoon Rock
- GlowingReed.MapEntry: Glowing Reed
- LampLotus.MapEntry: Lamp Lotus
- MothWorldDoor.MapEntry: Moth World Door
- CyanVineBar.MapEntry: Cyan Vine Bar
- CyanVineOreTile.MapEntry: Cyan Vine Ore Tile
- CyanVineStone.MapEntry: Cyan Vine Stone
- LiftLamp.MapEntry: Lift Lamp
-}
-
-Biomes: {
- TuskBiome: {
- DisplayName: Tusk Biome
- TownNPCDialogueName: the Tusk Biome
- }
-
- TuskSurfaceBiome: {
- DisplayName: Tusk Surface Biome
- TownNPCDialogueName: the Tusk Surface Biome
- }
-
- FireflyBiome: {
- DisplayName: Firefly Biome
- TownNPCDialogueName: the Firefly Biome
- }
-
- YggdrasilTownBiome: {
- DisplayName: Yggdrasil Town Biome
- TownNPCDialogueName: the Yggdrasil Town Biome
- }
-
- KelpCurtainBiome: {
- DisplayName: Kelp Curtain Biome
- TownNPCDialogueName: the Kelp Curtain Biome
- }
-}
-
-MapEntry.FluorescentTree: Mods.Everglow.MapEntry.FluorescentTree
-
-Buffs: {
- BloodSwordStrikeBuff: {
- DisplayName: Blood Sword Strike Buff
- Description: Mods.Everglow.Buffs.BloodSwordStrikeBuff.Description
- }
-
- LifeRotten: {
- DisplayName: Life Rotten
- Description: Mods.Everglow.Buffs.LifeRotten.Description
- }
-
- OnElectric: {
- DisplayName: On Electric
- Description: Mods.Everglow.Buffs.OnElectric.Description
- }
-
- StarCrack: {
- DisplayName: Star Crack
- Description: Mods.Everglow.Buffs.StarCrack.Description
- }
-
- AppleBuff: {
- DisplayName: Apple Buff
- Description: Mods.Everglow.Buffs.AppleBuff.Description
- }
-
- ApplePieBuff: {
- DisplayName: Apple Pie Buff
- Description: Mods.Everglow.Buffs.ApplePieBuff.Description
- }
-
- ApricotBuff: {
- DisplayName: Apricot Buff
- Description: Mods.Everglow.Buffs.ApricotBuff.Description
- }
-
- BaconBuff: {
- DisplayName: Bacon Buff
- Description: Mods.Everglow.Buffs.BaconBuff.Description
- }
-
- BananaBuff: {
- DisplayName: Banana Buff
- Description: Mods.Everglow.Buffs.BananaBuff.Description
- }
-
- BananaSplitBuff: {
- DisplayName: Banana Split Buff
- Description: Mods.Everglow.Buffs.BananaSplitBuff.Description
- }
-
- BBQRibsBuff: {
- DisplayName: B B Q Ribs Buff
- Description: Mods.Everglow.Buffs.BBQRibsBuff.Description
- }
-
- BlackCurrantBuff: {
- DisplayName: Black Currant Buff
- Description: Mods.Everglow.Buffs.BlackCurrantBuff.Description
- }
-
- BloodOrangeBuff: {
- DisplayName: Blood Orange Buff
- Description: Mods.Everglow.Buffs.BloodOrangeBuff.Description
- }
-
- BowlofSoupBuff: {
- DisplayName: Bowlof Soup Buff
- Description: Mods.Everglow.Buffs.BowlofSoupBuff.Description
- }
-
- BunnyStewBuff: {
- DisplayName: Bunny Stew Buff
- Description: Mods.Everglow.Buffs.BunnyStewBuff.Description
- }
-
- BurgerBuff: {
- DisplayName: Burger Buff
- Description: Mods.Everglow.Buffs.BurgerBuff.Description
- }
-
- CherryBuff: {
- DisplayName: Cherry Buff
- Description: Mods.Everglow.Buffs.CherryBuff.Description
- }
-
- ChickenNuggetBuff: {
- DisplayName: Chicken Nugget Buff
- Description: Mods.Everglow.Buffs.ChickenNuggetBuff.Description
- }
-
- ChocolateChipCookieBuff: {
- DisplayName: Chocolate Chip Cookie Buff
- Description: Mods.Everglow.Buffs.ChocolateChipCookieBuff.Description
- }
-
- ChristmasPuddingBuff: {
- DisplayName: Christmas Pudding Buff
- Description: Mods.Everglow.Buffs.ChristmasPuddingBuff.Description
- }
-
- CoconutBuff: {
- DisplayName: Coconut Buff
- Description: Mods.Everglow.Buffs.CoconutBuff.Description
- }
-
- CookedFishBuff: {
- DisplayName: Cooked Fish Buff
- Description: Mods.Everglow.Buffs.CookedFishBuff.Description
- }
-
- CookedMarshmallowBuff: {
- DisplayName: Cooked Marshmallow Buff
- Description: Mods.Everglow.Buffs.CookedMarshmallowBuff.Description
- }
-
- CookedShrimpBuff: {
- DisplayName: Cooked Shrimp Buff
- Description: Mods.Everglow.Buffs.CookedShrimpBuff.Description
- }
-
- DragonfruitBuff: {
- DisplayName: Dragonfruit Buff
- Description: Mods.Everglow.Buffs.DragonfruitBuff.Description
- }
-
- ElderberryBuff: {
- DisplayName: Elderberry Buff
- Description: Mods.Everglow.Buffs.ElderberryBuff.Description
- }
-
- EscargotBuff: {
- DisplayName: Escargot Buff
- Description: Mods.Everglow.Buffs.EscargotBuff.Description
- }
-
- FriedEggBuff: {
- DisplayName: Fried Egg Buff
- Description: Mods.Everglow.Buffs.FriedEggBuff.Description
- }
-
- FriesBuff: {
- DisplayName: Fries Buff
- Description: Mods.Everglow.Buffs.FriesBuff.Description
- }
-
- FroggleBunwichBuff: {
- DisplayName: Froggle Bunwich Buff
- Description: Mods.Everglow.Buffs.FroggleBunwichBuff.Description
- }
-
- FruitSaladBuff: {
- DisplayName: Fruit Salad Buff
- Description: Mods.Everglow.Buffs.FruitSaladBuff.Description
- }
-
- GingerbreadCookieBuff: {
- DisplayName: Gingerbread Cookie Buff
- Description: Mods.Everglow.Buffs.GingerbreadCookieBuff.Description
- }
-
- GoldenDelightBuff: {
- DisplayName: Golden Delight Buff
- Description: Mods.Everglow.Buffs.GoldenDelightBuff.Description
- }
-
- GrapefruitBuff: {
- DisplayName: Grapefruit Buff
- Description: Mods.Everglow.Buffs.GrapefruitBuff.Description
- }
-
- GrapesBuff: {
- DisplayName: Grapes Buff
- Description: Mods.Everglow.Buffs.GrapesBuff.Description
- }
-
- GrilledSquirrelBuff: {
- DisplayName: Grilled Squirrel Buff
- Description: Mods.Everglow.Buffs.GrilledSquirrelBuff.Description
- }
-
- GrubSoupBuff: {
- DisplayName: Grub Soup Buff
- Description: Mods.Everglow.Buffs.GrubSoupBuff.Description
- }
-
- HotdogBuff: {
- DisplayName: Hotdog Buff
- Description: Mods.Everglow.Buffs.HotdogBuff.Description
- }
-
- IceCreamBuff: {
- DisplayName: Ice Cream Buff
- Description: Mods.Everglow.Buffs.IceCreamBuff.Description
- }
-
- LemonBuff: {
- DisplayName: Lemon Buff
- Description: Mods.Everglow.Buffs.LemonBuff.Description
- }
-
- LobsterTailBuff: {
- DisplayName: Lobster Tail Buff
- Description: Mods.Everglow.Buffs.LobsterTailBuff.Description
- }
-
- MangoBuff: {
- DisplayName: Mango Buff
- Description: Mods.Everglow.Buffs.MangoBuff.Description
- }
-
- MarshmallowBuff: {
- DisplayName: Marshmallow Buff
- Description: Mods.Everglow.Buffs.MarshmallowBuff.Description
- }
-
- MonsterLasagnaBuff: {
- DisplayName: Monster Lasagna Buff
- Description: Mods.Everglow.Buffs.MonsterLasagnaBuff.Description
- }
-
- NachosBuff: {
- DisplayName: Nachos Buff
- Description: Mods.Everglow.Buffs.NachosBuff.Description
- }
-
- PadThaiBuff: {
- DisplayName: Pad Thai Buff
- Description: Mods.Everglow.Buffs.PadThaiBuff.Description
- }
-
- PeachBuff: {
- DisplayName: Peach Buff
- Description: Mods.Everglow.Buffs.PeachBuff.Description
- }
-
- PhoBuff: {
- DisplayName: Pho Buff
- Description: Mods.Everglow.Buffs.PhoBuff.Description
- }
-
- PineappleBuff: {
- DisplayName: Pineapple Buff
- Description: Mods.Everglow.Buffs.PineappleBuff.Description
- }
-
- PizzaBuff: {
- DisplayName: Pizza Buff
- Description: Mods.Everglow.Buffs.PizzaBuff.Description
- }
-
- PlumBuff: {
- DisplayName: Plum Buff
- Description: Mods.Everglow.Buffs.PlumBuff.Description
- }
-
- PotatoChipsBuff: {
- DisplayName: Potato Chips Buff
- Description: Mods.Everglow.Buffs.PotatoChipsBuff.Description
- }
-
- PumpkinPieBuff: {
- DisplayName: Pumpkin Pie Buff
- Description: Mods.Everglow.Buffs.PumpkinPieBuff.Description
- }
-
- RambutanBuff: {
- DisplayName: Rambutan Buff
- Description: Mods.Everglow.Buffs.RambutanBuff.Description
- }
-
- RoastedBirdBuff: {
- DisplayName: Roasted Bird Buff
- Description: Mods.Everglow.Buffs.RoastedBirdBuff.Description
- }
-
- RoastedDuckBuff: {
- DisplayName: Roasted Duck Buff
- Description: Mods.Everglow.Buffs.RoastedDuckBuff.Description
- }
-
- SashimiBuff: {
- DisplayName: Sashimi Buff
- Description: Mods.Everglow.Buffs.SashimiBuff.Description
- }
-
- SauteedFrogLegsBuff: {
- DisplayName: Sauteed Frog Legs Buff
- Description: Mods.Everglow.Buffs.SauteedFrogLegsBuff.Description
- }
-
- SeafoodDinnerBuff: {
- DisplayName: Seafood Dinner Buff
- Description: Mods.Everglow.Buffs.SeafoodDinnerBuff.Description
- }
-
- ShrimpPoBoyBuff: {
- DisplayName: Shrimp Po Boy Buff
- Description: Mods.Everglow.Buffs.ShrimpPoBoyBuff.Description
- }
-
- ShuckedOysterBuff: {
- DisplayName: Shucked Oyster Buff
- Description: Mods.Everglow.Buffs.ShuckedOysterBuff.Description
- }
-
- SpaghettiBuff: {
- DisplayName: Spaghetti Buff
- Description: Mods.Everglow.Buffs.SpaghettiBuff.Description
- }
-
- StarfruitBuff: {
- DisplayName: Starfruit Buff
- Description: Mods.Everglow.Buffs.StarfruitBuff.Description
- }
-
- SteakBuff: {
- DisplayName: Steak Buff
- Description: Mods.Everglow.Buffs.SteakBuff.Description
- }
-
- SugarCookieBuff: {
- DisplayName: Sugar Cookie Buff
- Description: Mods.Everglow.Buffs.SugarCookieBuff.Description
- }
-
- AleBuff: {
- DisplayName: Ale Buff
- Description: Mods.Everglow.Buffs.AleBuff.Description
- }
-
- AppleJuiceBuff: {
- DisplayName: Apple Juice Buff
- Description: Mods.Everglow.Buffs.AppleJuiceBuff.Description
- }
-
- BananaDaiquiriBuff: {
- DisplayName: Banana Daiquiri Buff
- Description: Mods.Everglow.Buffs.BananaDaiquiriBuff.Description
- }
-
- BloodyMoscatoBuff: {
- DisplayName: Bloody Moscato Buff
- Description: Mods.Everglow.Buffs.BloodyMoscatoBuff.Description
- }
-
- CoffeeCupBuff: {
- DisplayName: Coffee Cup Buff
- Description: Mods.Everglow.Buffs.CoffeeCupBuff.Description
- }
-
- CreamSodaBuff: {
- DisplayName: Cream Soda Buff
- Description: Mods.Everglow.Buffs.CreamSodaBuff.Description
- }
-
- FruitJuiceBuff: {
- DisplayName: Fruit Juice Buff
- Description: Mods.Everglow.Buffs.FruitJuiceBuff.Description
- }
-
- GrapeJuiceBuff: {
- DisplayName: Grape Juice Buff
- Description: Mods.Everglow.Buffs.GrapeJuiceBuff.Description
- }
-
- LemonadeBuff: {
- DisplayName: Lemonade Buff
- Description: Mods.Everglow.Buffs.LemonadeBuff.Description
- }
-
- MilkCartonBuff: {
- DisplayName: Milk Carton Buff
- Description: Mods.Everglow.Buffs.MilkCartonBuff.Description
- }
-
- MilkshakeBuff: {
- DisplayName: Milkshake Buff
- Description: Mods.Everglow.Buffs.MilkshakeBuff.Description
- }
-
- PeachSangriaBuff: {
- DisplayName: Peach Sangria Buff
- Description: Mods.Everglow.Buffs.PeachSangriaBuff.Description
- }
-
- PinaColadaBuff: {
- DisplayName: Pina Colada Buff
- Description: Mods.Everglow.Buffs.PinaColadaBuff.Description
- }
-
- PrismaticPunchBuff: {
- DisplayName: Prismatic Punch Buff
- Description: Mods.Everglow.Buffs.PrismaticPunchBuff.Description
- }
-
- SakeBuff: {
- DisplayName: Sake Buff
- Description: Mods.Everglow.Buffs.SakeBuff.Description
- }
-
- SmoothieofDarknessBuff: {
- DisplayName: Smoothieof Darkness Buff
- Description: Mods.Everglow.Buffs.SmoothieofDarknessBuff.Description
- }
-
- TeacupBuff: {
- DisplayName: Teacup Buff
- Description: Mods.Everglow.Buffs.TeacupBuff.Description
- }
-
- TropicalSmoothieBuff: {
- DisplayName: Tropical Smoothie Buff
- Description: Mods.Everglow.Buffs.TropicalSmoothieBuff.Description
- }
-
- ArcticshellfishWarshipBuff: {
- DisplayName: Arcticshellfish Warship Buff
- Description: Mods.Everglow.Buffs.ArcticshellfishWarshipBuff.Description
- }
-
- BakedMusselBuff: {
- DisplayName: Baked Mussel Buff
- Description: Mods.Everglow.Buffs.BakedMusselBuff.Description
- }
-
- BakedOysterBuff: {
- DisplayName: Baked Oyster Buff
- Description: Mods.Everglow.Buffs.BakedOysterBuff.Description
- }
-
- CantaloupeJellyBuff: {
- DisplayName: Cantaloupe Jelly Buff
- Description: Mods.Everglow.Buffs.CantaloupeJellyBuff.Description
- }
-
- CaramelPuddingBuff: {
- DisplayName: Caramel Pudding Buff
- Description: Mods.Everglow.Buffs.CaramelPuddingBuff.Description
- }
-
- CrabseedWarshipBuff: {
- DisplayName: Crabseed Warship Buff
- Description: Mods.Everglow.Buffs.CrabseedWarshipBuff.Description
- }
-
- DurianBuff: {
- DisplayName: Durian Buff
- Description: Mods.Everglow.Buffs.DurianBuff.Description
- }
-
- EggTartBuff: {
- DisplayName: Egg Tart Buff
- Description: Mods.Everglow.Buffs.EggTartBuff.Description
- }
-
- KiwiFruitBuff: {
- DisplayName: Kiwi Fruit Buff
- Description: Mods.Everglow.Buffs.KiwiFruitBuff.Description
- }
-
- KiwiIceCreamBuff: {
- DisplayName: Kiwi Ice Cream Buff
- Description: Mods.Everglow.Buffs.KiwiIceCreamBuff.Description
- }
-
- MangosteenBuff: {
- DisplayName: Mangosteen Buff
- Description: Mods.Everglow.Buffs.MangosteenBuff.Description
- }
-
- OrangeIcecreamBuff: {
- DisplayName: Orange Icecream Buff
- Description: Mods.Everglow.Buffs.OrangeIcecreamBuff.Description
- }
-
- SalmonInPepperBuff: {
- DisplayName: Salmon In Pepper Buff
- Description: Mods.Everglow.Buffs.SalmonInPepperBuff.Description
- }
-
- SalmonWarshipBuff: {
- DisplayName: Salmon Warship Buff
- Description: Mods.Everglow.Buffs.SalmonWarshipBuff.Description
- }
-
- SeafoodPizzaBuff: {
- DisplayName: Seafood Pizza Buff
- Description: Mods.Everglow.Buffs.SeafoodPizzaBuff.Description
- }
-
- StinkyTofuBuff: {
- DisplayName: Stinky Tofu Buff
- Description: Mods.Everglow.Buffs.StinkyTofuBuff.Description
- }
-
- StrawberryBuff: {
- DisplayName: Strawberry Buff
- Description: Mods.Everglow.Buffs.StrawberryBuff.Description
- }
-
- StrawberryIcecreamBuff: {
- DisplayName: Strawberry Icecream Buff
- Description: Mods.Everglow.Buffs.StrawberryIcecreamBuff.Description
- }
-
- SweetshrimpSushiBuff: {
- DisplayName: Sweetshrimp Sushi Buff
- Description: Mods.Everglow.Buffs.SweetshrimpSushiBuff.Description
- }
-
- TamakoSushiBuff: {
- DisplayName: Tamako Sushi Buff
- Description: Mods.Everglow.Buffs.TamakoSushiBuff.Description
- }
-
- WakameWarshipBuff: {
- DisplayName: Wakame Warship Buff
- Description: Mods.Everglow.Buffs.WakameWarshipBuff.Description
- }
-
- WatermelonBuff: {
- DisplayName: Watermelon Buff
- Description: Mods.Everglow.Buffs.WatermelonBuff.Description
- }
-
- WatermelonPlateBuff: {
- DisplayName: Watermelon Plate Buff
- Description: Mods.Everglow.Buffs.WatermelonPlateBuff.Description
- }
-
- BlueHawaiiBuff: {
- DisplayName: Blue Hawaii Buff
- Description: Mods.Everglow.Buffs.BlueHawaiiBuff.Description
- }
-
- B_52Buff: {
- DisplayName: B_52 Buff
- Description: Mods.Everglow.Buffs.B_52Buff.Description
- }
-
- DreamYearningBuff: {
- DisplayName: Dream Yearning Buff
- Description: Mods.Everglow.Buffs.DreamYearningBuff.Description
- }
-
- DryMartiniBuff: {
- DisplayName: Dry Martini Buff
- Description: Mods.Everglow.Buffs.DryMartiniBuff.Description
- }
-
- GreenStormBuff: {
- DisplayName: Green Storm Buff
- Description: Mods.Everglow.Buffs.GreenStormBuff.Description
- }
-
- KiwiJuiceBuff: {
- DisplayName: Kiwi Juice Buff
- Description: Mods.Everglow.Buffs.KiwiJuiceBuff.Description
- }
-
- LonelyJellyfishBuff: {
- DisplayName: Lonely Jellyfish Buff
- Description: Mods.Everglow.Buffs.LonelyJellyfishBuff.Description
- }
-
- OrangeJuiceBuff: {
- DisplayName: Orange Juice Buff
- Description: Mods.Everglow.Buffs.OrangeJuiceBuff.Description
- }
-
- PiercoldWindBuff: {
- DisplayName: Piercold Wind Buff
- Description: Mods.Everglow.Buffs.PiercoldWindBuff.Description
- }
-
- PurpleHooterBuff: {
- DisplayName: Purple Hooter Buff
- Description: Mods.Everglow.Buffs.PurpleHooterBuff.Description
- }
-
- QuinceMarryBuff: {
- DisplayName: Quince Marry Buff
- Description: Mods.Everglow.Buffs.QuinceMarryBuff.Description
- }
-
- RedWineBuff: {
- DisplayName: Red Wine Buff
- Description: Mods.Everglow.Buffs.RedWineBuff.Description
- }
-
- SunriseBuff: {
- DisplayName: Sunrise Buff
- Description: Mods.Everglow.Buffs.SunriseBuff.Description
- }
-
- TricolourBuff: {
- DisplayName: Tricolour Buff
- Description: Mods.Everglow.Buffs.TricolourBuff.Description
- }
-
- WaterMelonJuiceBuff: {
- DisplayName: Water Melon Juice Buff
- Description: Mods.Everglow.Buffs.WaterMelonJuiceBuff.Description
- }
-
- TuskStaff: {
- DisplayName: Tusk Staff
- Description: Mods.Everglow.Buffs.TuskStaff.Description
- }
-
- GlowMothBuff: {
- DisplayName: Glow Moth Buff
- Description: Mods.Everglow.Buffs.GlowMothBuff.Description
- }
-
- OnMoth: {
- DisplayName: On Moth
- Description: Mods.Everglow.Buffs.OnMoth.Description
- }
-
- Freeze: {
- DisplayName: Freeze
- Description: Mods.Everglow.Buffs.Freeze.Description
- }
-
- LaserWormBuff: {
- DisplayName: Laser Worm Buff
- Description: Mods.Everglow.Buffs.LaserWormBuff.Description
- }
-
- ShadowSupervisor: {
- DisplayName: Shadow Supervisor
- Description: Mods.Everglow.Buffs.ShadowSupervisor.Description
- }
-
- MoonAndFragrans: {
- DisplayName: Moon And Fragrans
- Description: Mods.Everglow.Buffs.MoonAndFragrans.Description
- }
-
- MoonAndFragransII: {
- DisplayName: Moon And Fragrans I I
- Description: Mods.Everglow.Buffs.MoonAndFragransII.Description
- }
-
- MoonAndFragransIII: {
- DisplayName: Moon And Fragrans I I I
- Description: Mods.Everglow.Buffs.MoonAndFragransIII.Description
- }
-
- WaterBoltII: {
- DisplayName: Water Bolt I I
- Description: Mods.Everglow.Buffs.WaterBoltII.Description
- }
-
- BlueImmune: {
- DisplayName: Blue Immune
- Description: Mods.Everglow.Buffs.BlueImmune.Description
- }
-
- BrownImmune: {
- DisplayName: Brown Immune
- Description: Mods.Everglow.Buffs.BrownImmune.Description
- }
-
- GreenImmune: {
- DisplayName: Green Immune
- Description: Mods.Everglow.Buffs.GreenImmune.Description
- }
-
- PinkImmune: {
- DisplayName: Pink Immune
- Description: Mods.Everglow.Buffs.PinkImmune.Description
- }
-
- PurpleImmune: {
- DisplayName: Purple Immune
- Description: Mods.Everglow.Buffs.PurpleImmune.Description
- }
-
- RedImmune: {
- DisplayName: Red Immune
- Description: Mods.Everglow.Buffs.RedImmune.Description
- }
-
- WhiteImmune: {
- DisplayName: White Immune
- Description: Mods.Everglow.Buffs.WhiteImmune.Description
- }
-
- YellowImmune: {
- DisplayName: Yellow Immune
- Description: Mods.Everglow.Buffs.YellowImmune.Description
- }
-
- CactusBallBuff: {
- DisplayName: Cactus Ball Buff
- Description: Mods.Everglow.Buffs.CactusBallBuff.Description
- }
-
- DeathFlame: {
- DisplayName: Death Flame
- Description: Mods.Everglow.Buffs.DeathFlame.Description
- }
-}
-
-Items: {
- BottleOfNutShellFlowers: {
- DisplayName: Bottle Of Nut Shell Flowers
- Tooltip: ""
- }
-
- PlumBlossomInABowl: {
- DisplayName: Plum Blossom In A Bowl
- Tooltip: ""
- }
-
- WhiteLotusBonsai: {
- DisplayName: White Lotus Bonsai
- Tooltip: ""
- }
-
- BloodGoldBayonet: {
- DisplayName: Blood Gold Bayonet
- Tooltip: ""
- }
-
- BlueRibbonBayonet: {
- DisplayName: Blue Ribbon Bayonet
- Tooltip: ""
- }
-
- CopperBayonet: {
- DisplayName: Copper Bayonet
- Tooltip: ""
- }
-
- DreamStar: {
- DisplayName: Dream Star
- Tooltip: ""
- }
-
- EnchantedBayonet: {
- DisplayName: Enchanted Bayonet
- Tooltip: ""
- }
-
- EternalNight: {
- DisplayName: Eternal Night
- Tooltip: ""
- }
-
- GoldenStabbingSword: {
- DisplayName: Golden Stabbing Sword
- Tooltip: ""
- }
-
- HolyBayonet: {
- DisplayName: Holy Bayonet
- Tooltip: ""
- }
-
- IronStabbingSword: {
- DisplayName: Iron Stabbing Sword
- Tooltip: ""
- }
-
- LeadStabbingSword: {
- DisplayName: Lead Stabbing Sword
- Tooltip: ""
- }
-
- PlatinumStabbingSword: {
- DisplayName: Platinum Stabbing Sword
- Tooltip: ""
- }
-
- PrisonFireBayonet: {
- DisplayName: Prison Fire Bayonet
- Tooltip: ""
- }
-
- RedRibbonBayonet: {
- DisplayName: Red Ribbon Bayonet
- Tooltip: ""
- }
-
- RottenGoldBayonet: {
- DisplayName: Rotten Gold Bayonet
- Tooltip: ""
- }
-
- SilverStabbingSword: {
- DisplayName: Silver Stabbing Sword
- Tooltip: ""
- }
-
- TinStabbingSword: {
- DisplayName: Tin Stabbing Sword
- Tooltip: ""
- }
-
- TungstenStabbingSword: {
- DisplayName: Tungsten Stabbing Sword
- Tooltip: ""
- }
-
- VegetationBayonet: {
- DisplayName: Vegetation Bayonet
- Tooltip: ""
- }
-
- YoenLeZed: {
- DisplayName: Yoen Le Zed
- Tooltip: ""
- }
-
- StarSeed: {
- DisplayName: Star Seed
- Tooltip: ""
- }
-
- FryingPanItem: {
- DisplayName: Frying Pan Item
- Tooltip: ""
- }
-
- BloodGlucoseMonitor: {
- DisplayName: Blood Glucose Monitor
- Tooltip: ""
- }
-
- OsmoticPressureMonitor: {
- DisplayName: Osmotic Pressure Monitor
- Tooltip: ""
- }
-
- ArcticshellfishWarship: {
- DisplayName: Arcticshellfish Warship
- Tooltip: ""
- }
-
- BakedMussel: {
- DisplayName: Baked Mussel
- Tooltip: ""
- }
-
- BakedOyster: {
- DisplayName: Baked Oyster
- Tooltip: ""
- }
-
- CantaloupeJelly: {
- DisplayName: Cantaloupe Jelly
- Tooltip: ""
- }
-
- CaramelPudding: {
- DisplayName: Caramel Pudding
- Tooltip: ""
- }
-
- CrabseedWarship: {
- DisplayName: Crabseed Warship
- Tooltip: ""
- }
-
- Durian: {
- DisplayName: Durian
- Tooltip: ""
- }
-
- EggTart: {
- DisplayName: Egg Tart
- Tooltip: ""
- }
-
- KiwiFruit: {
- DisplayName: Kiwi Fruit
- Tooltip: ""
- }
-
- KiwiIceCream: {
- DisplayName: Kiwi Ice Cream
- Tooltip: ""
- }
-
- Mangosteen: {
- DisplayName: Mangosteen
- Tooltip: ""
- }
-
- OrangeIcecream: {
- DisplayName: Orange Icecream
- Tooltip: ""
- }
-
- SalmonInPepper: {
- DisplayName: Salmon In Pepper
- Tooltip: ""
- }
-
- SalmonWarship: {
- DisplayName: Salmon Warship
- Tooltip: ""
- }
-
- SeafoodPizza: {
- DisplayName: Seafood Pizza
- Tooltip: ""
- }
-
- StinkyTofu: {
- DisplayName: Stinky Tofu
- Tooltip: ""
- }
-
- Strawberry: {
- DisplayName: Strawberry
- Tooltip: ""
- }
-
- StrawberryIcecream: {
- DisplayName: Strawberry Icecream
- Tooltip: ""
- }
-
- SweetshrimpSushi: {
- DisplayName: Sweetshrimp Sushi
- Tooltip: ""
- }
-
- TamakoSushi: {
- DisplayName: Tamako Sushi
- Tooltip: ""
- }
-
- WakameWarship: {
- DisplayName: Wakame Warship
- Tooltip: ""
- }
-
- Watermelon: {
- DisplayName: Watermelon
- Tooltip: ""
- }
-
- WatermelonPlate: {
- DisplayName: Watermelon Plate
- Tooltip: ""
- }
-
- BlueHawaii: {
- DisplayName: Blue Hawaii
- Tooltip: ""
- }
-
- B_52: {
- DisplayName: B_52
- Tooltip: ""
- }
-
- DreamYearning: {
- DisplayName: Dream Yearning
- Tooltip: ""
- }
-
- DryMartini: {
- DisplayName: Dry Martini
- Tooltip: ""
- }
-
- GreenStorm: {
- DisplayName: Green Storm
- Tooltip: ""
- }
-
- KiwiJuice: {
- DisplayName: Kiwi Juice
- Tooltip: ""
- }
-
- LonelyJellyfish: {
- DisplayName: Lonely Jellyfish
- Tooltip: ""
- }
-
- OrangeJuice: {
- DisplayName: Orange Juice
- Tooltip: ""
- }
-
- PiercoldWind: {
- DisplayName: Piercold Wind
- Tooltip: ""
- }
-
- PurpleHooter: {
- DisplayName: Purple Hooter
- Tooltip: ""
- }
-
- QuinceMarry: {
- DisplayName: Quince Marry
- Tooltip: ""
- }
-
- RedWine: {
- DisplayName: Red Wine
- Tooltip: ""
- }
-
- Sunrise: {
- DisplayName: Sunrise
- Tooltip: ""
- }
-
- Tricolour: {
- DisplayName: Tricolour
- Tooltip: ""
- }
-
- WaterMelonJuice: {
- DisplayName: Water Melon Juice
- Tooltip: ""
- }
-
- VFXGenerator: {
- DisplayName: V F X Generator
- Tooltip: ""
- }
-
- AirTileItem: {
- DisplayName: Air Tile Item
- Tooltip: ""
- }
-
- AirWallItem: {
- DisplayName: Air Wall Item
- Tooltip: ""
- }
-
- VortexVanquisherItem: {
- DisplayName: Vortex Vanquisher Item
- Tooltip: ""
- }
-
- Tester: {
- DisplayName: Tester
- Tooltip: ""
- }
-
- BloodMossStone: {
- DisplayName: Blood Moss Stone
- Tooltip: ""
- }
-
- BloodyStoneWall: {
- DisplayName: Bloody Stone Wall
- Tooltip: ""
- }
-
- StoneTusk: {
- DisplayName: Stone Tusk
- Tooltip: ""
- }
-
- TuskFlesh: {
- DisplayName: Tusk Flesh
- Tooltip: ""
- }
-
- TuskStatusI: {
- DisplayName: Tusk Status I
- Tooltip: ""
- }
-
- TuskStatusII: {
- DisplayName: Tusk Status I I
- Tooltip: ""
- }
-
- TuskStatusIII: {
- DisplayName: Tusk Status I I I
- Tooltip: ""
- }
-
- TuskStatusIV: {
- DisplayName: Tusk Status I V
- Tooltip: ""
- }
-
- BloodyBoneYoyo: {
- DisplayName: Bloody Bone Yoyo
- Tooltip: ""
- }
-
- SpineGun: {
- DisplayName: Spine Gun
- Tooltip: ""
- }
-
- ToothBow: {
- DisplayName: Tooth Bow
- Tooltip: ""
- }
-
- ToothKnife: {
- DisplayName: Tooth Knife
- Tooltip: ""
- }
-
- ToothMagicBall: {
- DisplayName: Tooth Magic Ball
- Tooltip: ""
- }
-
- ToothSpear: {
- DisplayName: Tooth Spear
- Tooltip: ""
- }
-
- ToothStaff: {
- DisplayName: Tooth Staff
- Tooltip: ""
- }
-
- BloodyTuskTrophy: {
- DisplayName: Bloody Tusk Trophy
- Tooltip: ""
- }
-
- TuskRelic: {
- DisplayName: Tusk Relic
- Tooltip: ""
- }
-
- TuskTreasureBag: {
- DisplayName: Tusk Treasure Bag
- Tooltip: ""
- }
-
- TuskLace: {
- DisplayName: Tusk Lace
- Tooltip: ""
- }
-
- FireflyPylonItem: {
- DisplayName: Firefly Pylon Item
- Tooltip: ""
- }
-
- ShabbyPylonItem: {
- DisplayName: Shabby Pylon Item
- Tooltip: ""
- }
-
- BlackStarShrub: {
- DisplayName: Black Star Shrub
- Tooltip: ""
- }
-
- DarkCocoon: {
- DisplayName: Dark Cocoon
- Tooltip: ""
- }
-
- DarkCocoonWall: {
- DisplayName: Dark Cocoon Wall
- Tooltip: ""
- }
-
- EvilCocoon: {
- DisplayName: Evil Cocoon
- Tooltip: ""
- }
-
- FireflyCapital: {
- DisplayName: Firefly Capital
- Tooltip: ""
- }
-
- FireflyMoss: {
- DisplayName: Firefly Moss
- Tooltip: ""
- }
-
- FireflyPigment: {
- DisplayName: Firefly Pigment
- Tooltip: ""
- }
-
- GlowCrystal: {
- DisplayName: Glow Crystal
- Tooltip: ""
- }
-
- GlowingFirefly: {
- DisplayName: Glowing Firefly
- Tooltip: ""
- }
-
- GlowingPedal: {
- DisplayName: Glowing Pedal
- Tooltip: ""
- }
-
- GlowMetal: {
- DisplayName: Glow Metal
- Tooltip: ""
- }
-
- GlowStone: {
- DisplayName: Glow Stone
- Tooltip: ""
- }
-
- GlowWood: {
- DisplayName: Glow Wood
- Tooltip: ""
- }
-
- LiveFluorescentLeafWall: {
- DisplayName: Live Fluorescent Leaf Wall
- Tooltip: ""
- }
-
- LiveFluorescentWoodWall: {
- DisplayName: Live Fluorescent Wood Wall
- Tooltip: ""
- }
-
- MothScaleDust: {
- DisplayName: Moth Scale Dust
- Tooltip: ""
- }
-
- DarknessFan: {
- DisplayName: Darkness Fan
- Tooltip: ""
- }
-
- DreamWeaver: {
- DisplayName: Dream Weaver
- Tooltip: ""
- }
-
- DustOfCorrupt: {
- DisplayName: Dust Of Corrupt
- Tooltip: ""
- }
-
- EvilChrysalis: {
- DisplayName: Evil Chrysalis
- Tooltip: ""
- }
-
- FlowLightMissile: {
- DisplayName: Flow Light Missile
- Tooltip: ""
- }
-
- GlowBeadGun: {
- DisplayName: Glow Bead Gun
- Tooltip: ""
- }
-
- GlowWoodSword: {
- DisplayName: Glow Wood Sword
- Tooltip: ""
- }
-
- MothYoyo: {
- DisplayName: Moth Yoyo
- Tooltip: ""
- }
-
- NavyThunder: {
- DisplayName: Navy Thunder
- Tooltip: ""
- }
-
- PhosphorescenceGun: {
- DisplayName: Phosphorescence Gun
- Tooltip: ""
- }
-
- ScaleWingBlade: {
- DisplayName: Scale Wing Blade
- Tooltip: ""
- }
-
- ShadowWingBow: {
- DisplayName: Shadow Wing Bow
- Tooltip: ""
- }
-
- FluorescentLeafStaff: {
- DisplayName: Fluorescent Leaf Staff
- Tooltip: ""
- }
-
- FluorescentWoodStaff: {
- DisplayName: Fluorescent Wood Staff
- Tooltip: ""
- }
-
- GlowingDrop: {
- DisplayName: Glowing Drop
- Tooltip: ""
- }
-
- GlowWoodBed: {
- DisplayName: Glow Wood Bed
- Tooltip: ""
- }
-
- GlowWoodBookcase: {
- DisplayName: Glow Wood Bookcase
- Tooltip: ""
- }
-
- GlowWoodBookcaseType2: {
- DisplayName: Glow Wood Bookcase Type2
- Tooltip: ""
- }
-
- GlowWoodCampfire: {
- DisplayName: Glow Wood Campfire
- Tooltip: ""
- }
-
- GlowWoodCandelabra: {
- DisplayName: Glow Wood Candelabra
- Tooltip: ""
- }
-
- GlowWoodCandle: {
- DisplayName: Glow Wood Candle
- Tooltip: ""
- }
-
- GlowWoodChair: {
- DisplayName: Glow Wood Chair
- Tooltip: ""
- }
-
- GlowWoodChandelier: {
- DisplayName: Glow Wood Chandelier
- Tooltip: ""
- }
-
- GlowWoodChandelierType2: {
- DisplayName: Glow Wood Chandelier Type2
- Tooltip: ""
- }
-
- GlowWoodChandelierType3: {
- DisplayName: Glow Wood Chandelier Type3
- Tooltip: ""
- }
-
- GlowWoodChandelierType4: {
- DisplayName: Glow Wood Chandelier Type4
- Tooltip: ""
- }
-
- GlowWoodChest: {
- DisplayName: Glow Wood Chest
- Tooltip: ""
- }
-
- GlowWoodClock: {
- DisplayName: Glow Wood Clock
- Tooltip: ""
- }
-
- GlowWoodDoor: {
- DisplayName: Glow Wood Door
- Tooltip: ""
- }
-
- GlowWoodDoorType2: {
- DisplayName: Glow Wood Door Type2
- Tooltip: ""
- }
-
- GlowWoodDresser: {
- DisplayName: Glow Wood Dresser
- Tooltip: ""
- }
-
- GlowWoodDresserType2: {
- DisplayName: Glow Wood Dresser Type2
- Tooltip: ""
- }
-
- GlowWoodLamp: {
- DisplayName: Glow Wood Lamp
- Tooltip: ""
- }
-
- GlowWoodLantern: {
- DisplayName: Glow Wood Lantern
- Tooltip: ""
- }
-
- GlowWoodLanternType2: {
- DisplayName: Glow Wood Lantern Type2
- Tooltip: ""
- }
-
- GlowWoodMusicBox: {
- DisplayName: Glow Wood Music Box
- Tooltip: ""
- }
-
- GlowWoodPiano: {
- DisplayName: Glow Wood Piano
- Tooltip: ""
- }
-
- GlowWoodPlatform: {
- DisplayName: Glow Wood Platform
- Tooltip: ""
- }
-
- GlowWoodSink: {
- DisplayName: Glow Wood Sink
- Tooltip: ""
- }
-
- GlowWoodSinkType2: {
- DisplayName: Glow Wood Sink Type2
- Tooltip: ""
- }
-
- GlowWoodSofa: {
- DisplayName: Glow Wood Sofa
- Tooltip: ""
- }
-
- GlowWoodSofaType2: {
- DisplayName: Glow Wood Sofa Type2
- Tooltip: ""
- }
-
- GlowWoodTable: {
- DisplayName: Glow Wood Table
- Tooltip: ""
- }
-
- GlowWoodTorch: {
- DisplayName: Glow Wood Torch
- Tooltip: ""
- }
-
- GlowWoodWorkBench: {
- DisplayName: Glow Wood Work Bench
- Tooltip: ""
- }
-
- CorruptMothTreasureBag: {
- DisplayName: Corrupt Moth Treasure Bag
- Tooltip: ""
- }
-
- MothRelic: {
- DisplayName: Moth Relic
- Tooltip: ""
- }
-
- FireflyBorageBadge: {
- DisplayName: Firefly Borage Badge
- Tooltip: ""
- }
-
- MothEye: {
- DisplayName: Moth Eye
- Tooltip: ""
- }
-
- LilyHarp: {
- DisplayName: Lily Harp
- Tooltip: ""
- }
-
- BlueflowerBra: {
- DisplayName: Blueflower Bra
- Tooltip: ""
- }
-
- BlueflowerCap: {
- DisplayName: Blueflower Cap
- Tooltip: ""
- }
-
- BlueflowerDress: {
- DisplayName: Blueflower Dress
- Tooltip: ""
- }
-
- AshBone: {
- DisplayName: Ash Bone
- Tooltip: ""
- }
-
- BoneFeatherMagic: {
- DisplayName: Bone Feather Magic
- Tooltip: ""
- }
-
- CloudGun: {
- DisplayName: Cloud Gun
- Tooltip: ""
- }
-
- ComingGhost: {
- DisplayName: Coming Ghost
- Tooltip: ""
- }
-
- CyanFrost: {
- DisplayName: Cyan Frost
- Tooltip: ""
- }
-
- FeatherMagic: {
- DisplayName: Feather Magic
- Tooltip: ""
- }
-
- FireFeatherMagic: {
- DisplayName: Fire Feather Magic
- Tooltip: ""
- }
-
- FreezeFeatherMagic: {
- DisplayName: Freeze Feather Magic
- Tooltip: ""
- }
-
- GoldRoundYoyo: {
- DisplayName: Gold Round Yoyo
- Tooltip: ""
- }
-
- GoldRound: {
- DisplayName: Gold Round
- Tooltip: ""
- }
-
- Hepuyuan: {
- DisplayName: Hepuyuan
- Tooltip: ""
- }
-
- SilveralGun: {
- DisplayName: Silveral Gun
- Tooltip: ""
- }
-
- SilveralRifle: {
- DisplayName: Silveral Rifle
- Tooltip: ""
- }
-
- Sunflower: {
- DisplayName: Sunflower
- Tooltip: ""
- }
-
- ThunderFlower: {
- DisplayName: Thunder Flower
- Tooltip: ""
- }
-
- World: {
- DisplayName: World
- Tooltip: ""
- }
-
- XmasWhip: {
- DisplayName: Xmas Whip
- Tooltip: ""
- }
-
- AmbiguousNight: {
- DisplayName: Ambiguous Night
- Tooltip: ""
- }
-
- AmethystSlingshot: {
- DisplayName: Amethyst Slingshot
- Tooltip: ""
- }
-
- BorealWoodSlingshot: {
- DisplayName: Boreal Wood Slingshot
- Tooltip: ""
- }
-
- CactusSlingShot: {
- DisplayName: Cactus Sling Shot
- Tooltip: ""
- }
-
- DiamondSlingshot: {
- DisplayName: Diamond Slingshot
- Tooltip: ""
- }
-
- EbonwoodSlingshot: {
- DisplayName: Ebonwood Slingshot
- Tooltip: ""
- }
-
- EmeraldSlingshot: {
- DisplayName: Emerald Slingshot
- Tooltip: ""
- }
-
- GelSlingshot: {
- DisplayName: Gel Slingshot
- Tooltip: ""
- }
-
- JungleSlingshot: {
- DisplayName: Jungle Slingshot
- Tooltip: ""
- }
-
- PalmWoodSlingshot: {
- DisplayName: Palm Wood Slingshot
- Tooltip: ""
- }
-
- PearlwoodSlingshot: {
- DisplayName: Pearlwood Slingshot
- Tooltip: ""
- }
-
- RichMahoganySlingshot: {
- DisplayName: Rich Mahogany Slingshot
- Tooltip: ""
- }
-
- RubySlingshot: {
- DisplayName: Ruby Slingshot
- Tooltip: ""
- }
-
- SapphireSlingshot: {
- DisplayName: Sapphire Slingshot
- Tooltip: ""
- }
-
- ShadewoodSlingShot: {
- DisplayName: Shadewood Sling Shot
- Tooltip: ""
- }
-
- StarSlingshot: {
- DisplayName: Star Slingshot
- Tooltip: ""
- }
-
- TopazSlingshot: {
- DisplayName: Topaz Slingshot
- Tooltip: ""
- }
-
- WoodSlingshot: {
- DisplayName: Wood Slingshot
- Tooltip: ""
- }
-
- AdamantiteClub: {
- DisplayName: Adamantite Club
- Tooltip: ""
- }
-
- BorealWoodClub: {
- DisplayName: Boreal Wood Club
- Tooltip: ""
- }
-
- CactusClub: {
- DisplayName: Cactus Club
- Tooltip: ""
- }
-
- ChlorophyteClub: {
- DisplayName: Chlorophyte Club
- Tooltip: ""
- }
-
- CobaltClub: {
- DisplayName: Cobalt Club
- Tooltip: ""
- }
-
- CopperClub: {
- DisplayName: Copper Club
- Tooltip: ""
- }
-
- CorruptClub: {
- DisplayName: Corrupt Club
- Tooltip: ""
- }
-
- CrimsonClub: {
- DisplayName: Crimson Club
- Tooltip: ""
- }
-
- CrystalClub: {
- DisplayName: Crystal Club
- Tooltip: ""
- }
-
- CurseClub: {
- DisplayName: Curse Club
- Tooltip: ""
- }
-
- EbonwoodClub: {
- DisplayName: Ebonwood Club
- Tooltip: ""
- }
-
- GoldClub: {
- DisplayName: Gold Club
- Tooltip: ""
- }
-
- IchorClub: {
- DisplayName: Ichor Club
- Tooltip: ""
- }
-
- IronClub: {
- DisplayName: Iron Club
- Tooltip: ""
- }
-
- LeadClub: {
- DisplayName: Lead Club
- Tooltip: ""
- }
-
- MeteorClub: {
- DisplayName: Meteor Club
- Tooltip: ""
- }
-
- MithrilClub: {
- DisplayName: Mithril Club
- Tooltip: ""
- }
-
- OrichalcumClub: {
- DisplayName: Orichalcum Club
- Tooltip: ""
- }
-
- PalladiumClub: {
- DisplayName: Palladium Club
- Tooltip: ""
- }
-
- PalmWoodClub: {
- DisplayName: Palm Wood Club
- Tooltip: ""
- }
-
- PearlwoodClub: {
- DisplayName: Pearlwood Club
- Tooltip: ""
- }
-
- PlatinumClub: {
- DisplayName: Platinum Club
- Tooltip: ""
- }
-
- RichMahoganyClub: {
- DisplayName: Rich Mahogany Club
- Tooltip: ""
- }
-
- ShadewoodClub: {
- DisplayName: Shadewood Club
- Tooltip: ""
- }
-
- SilverClub: {
- DisplayName: Silver Club
- Tooltip: ""
- }
-
- SpikeClub: {
- DisplayName: Spike Club
- Tooltip: ""
- }
-
- StarDancer: {
- DisplayName: Star Dancer
- Tooltip: ""
- }
-
- TinClub: {
- DisplayName: Tin Club
- Tooltip: ""
- }
-
- TitaniumClub: {
- DisplayName: Titanium Club
- Tooltip: ""
- }
-
- TungstenClub: {
- DisplayName: Tungsten Club
- Tooltip: ""
- }
-
- WoodenClub: {
- DisplayName: Wooden Club
- Tooltip: ""
- }
-
- CloudBall: {
- DisplayName: Cloud Ball
- Tooltip: ""
- }
-
- BlueGel: {
- DisplayName: Blue Gel
- Tooltip: ""
- }
-
- CorruptEye: {
- DisplayName: Corrupt Eye
- Tooltip: ""
- }
-
- DukeTooth: {
- DisplayName: Duke Tooth
- Tooltip: ""
- }
-
- GoldLiquidPupil: {
- DisplayName: Gold Liquid Pupil
- Tooltip: ""
- }
-
- GreenGel: {
- DisplayName: Green Gel
- Tooltip: ""
- }
-
- JungleVitamin: {
- DisplayName: Jungle Vitamin
- Tooltip: ""
- }
-
- Odd8Ring: {
- DisplayName: Odd8 Ring
- Tooltip: ""
- }
-
- RedGel: {
- DisplayName: Red Gel
- Tooltip: ""
- }
-
- SilverWing: {
- DisplayName: Silver Wing
- Tooltip: ""
- }
-
- WalnutClip: {
- DisplayName: Walnut Clip
- Tooltip: ""
- }
-
- FixCoinCrit1: {
- DisplayName: Fix Coin Crit1
- Tooltip: ""
- }
-
- FixCoinCrit2: {
- DisplayName: Fix Coin Crit2
- Tooltip: ""
- }
-
- FixCoinCrit3: {
- DisplayName: Fix Coin Crit3
- Tooltip: ""
- }
-
- FixCoinCrit4: {
- DisplayName: Fix Coin Crit4
- Tooltip: ""
- }
-
- FixCoinCrit5: {
- DisplayName: Fix Coin Crit5
- Tooltip: ""
- }
-
- FixCoinDamage1: {
- DisplayName: Fix Coin Damage1
- Tooltip: ""
- }
-
- FixCoinDamage2: {
- DisplayName: Fix Coin Damage2
- Tooltip: ""
- }
-
- FixCoinDamage3: {
- DisplayName: Fix Coin Damage3
- Tooltip: ""
- }
-
- FixCoinDamage4: {
- DisplayName: Fix Coin Damage4
- Tooltip: ""
- }
-
- FixCoinDamage5: {
- DisplayName: Fix Coin Damage5
- Tooltip: ""
- }
-
- FixCoinDefense1: {
- DisplayName: Fix Coin Defense1
- Tooltip: ""
- }
-
- FixCoinDefense2: {
- DisplayName: Fix Coin Defense2
- Tooltip: ""
- }
-
- FixCoinDefense3: {
- DisplayName: Fix Coin Defense3
- Tooltip: ""
- }
-
- FixCoinDefense4: {
- DisplayName: Fix Coin Defense4
- Tooltip: ""
- }
-
- FixCoinDefense5: {
- DisplayName: Fix Coin Defense5
- Tooltip: ""
- }
-
- FixCoinMelee1: {
- DisplayName: Fix Coin Melee1
- Tooltip: ""
- }
-
- FixCoinMelee2: {
- DisplayName: Fix Coin Melee2
- Tooltip: ""
- }
-
- FixCoinMelee3: {
- DisplayName: Fix Coin Melee3
- Tooltip: ""
- }
-
- FixCoinSpeed1: {
- DisplayName: Fix Coin Speed1
- Tooltip: ""
- }
-
- FixCoinSpeed2: {
- DisplayName: Fix Coin Speed2
- Tooltip: ""
- }
-
- FixCoinSpeed3: {
- DisplayName: Fix Coin Speed3
- Tooltip: ""
- }
-
- CrystalSkull: {
- DisplayName: Crystal Skull
- Tooltip: ""
- }
-
- BloodLamp: {
- DisplayName: Blood Lamp
- Tooltip: ""
- }
-
- LanternBombRemoteControl: {
- DisplayName: Lantern Bomb Remote Control
- Tooltip: ""
- }
-
- CactusBall: {
- DisplayName: Cactus Ball
- Tooltip: ""
- }
-
- BlueFreeze: {
- DisplayName: Blue Freeze
- Tooltip: ""
- }
-
- BluePedal: {
- DisplayName: Blue Pedal
- Tooltip: ""
- }
-
- CyanHyacinth: {
- DisplayName: Cyan Hyacinth
- Tooltip: ""
- }
-
- DarkPoppy: {
- DisplayName: Dark Poppy
- Tooltip: ""
- }
-
- FlowerBrochure: {
- DisplayName: Flower Brochure
- Tooltip: ""
- }
-
- GoldCup: {
- DisplayName: Gold Cup
- Tooltip: ""
- }
-
- GoldWhip: {
- DisplayName: Gold Whip
- Tooltip: ""
- }
-
- HotPinkTulip: {
- DisplayName: Hot Pink Tulip
- Tooltip: ""
- }
-
- Lavender: {
- DisplayName: Lavender
- Tooltip: ""
- }
-
- LightChrysanthemum: {
- DisplayName: Light Chrysanthemum
- Tooltip: ""
- }
-
- LightPurpleBalls: {
- DisplayName: Light Purple Balls
- Tooltip: ""
- }
-
- OrangeSausage: {
- DisplayName: Orange Sausage
- Tooltip: ""
- }
-
- OrangeTulip: {
- DisplayName: Orange Tulip
- Tooltip: ""
- }
-
- PinkSun: {
- DisplayName: Pink Sun
- Tooltip: ""
- }
-
- PurplePhantom: {
- DisplayName: Purple Phantom
- Tooltip: ""
- }
-
- PurpleTail: {
- DisplayName: Purple Tail
- Tooltip: ""
- }
-
- RedFlame: {
- DisplayName: Red Flame
- Tooltip: ""
- }
-
- ShallowNight: {
- DisplayName: Shallow Night
- Tooltip: ""
- }
-
- SilverClock: {
- DisplayName: Silver Clock
- Tooltip: ""
- }
-
- WhiteStar: {
- DisplayName: White Star
- Tooltip: ""
- }
-
- WhiteTulip: {
- DisplayName: White Tulip
- Tooltip: ""
- }
-
- WindMoveSeed: {
- DisplayName: Wind Move Seed
- Tooltip: ""
- }
-
- BlueTorchFlower: {
- DisplayName: Blue Torch Flower
- Tooltip: ""
- }
-
- CyanBranch: {
- DisplayName: Cyan Branch
- Tooltip: ""
- }
-
- CyanPedal: {
- DisplayName: Cyan Pedal
- Tooltip: ""
- }
-
- DarkHat: {
- DisplayName: Dark Hat
- Tooltip: ""
- }
-
- HotPinkCrown: {
- DisplayName: Hot Pink Crown
- Tooltip: ""
- }
-
- LightPurplePen: {
- DisplayName: Light Purple Pen
- Tooltip: ""
- }
-
- ManyWhiteFlower: {
- DisplayName: Many White Flower
- Tooltip: ""
- }
-
- OrangeCrown: {
- DisplayName: Orange Crown
- Tooltip: ""
- }
-
- OrangeStick: {
- DisplayName: Orange Stick
- Tooltip: ""
- }
-
- PinkFourPedal: {
- DisplayName: Pink Four Pedal
- Tooltip: ""
- }
-
- PurpleBall: {
- DisplayName: Purple Ball
- Tooltip: ""
- }
-
- PurpleReedHalo: {
- DisplayName: Purple Reed Halo
- Tooltip: ""
- }
-
- RedTriangle: {
- DisplayName: Red Triangle
- Tooltip: ""
- }
-
- SilverCupFlower: {
- DisplayName: Silver Cup Flower
- Tooltip: ""
- }
-
- ThreeColorCrown: {
- DisplayName: Three Color Crown
- Tooltip: ""
- }
-
- WhiteCrown: {
- DisplayName: White Crown
- Tooltip: ""
- }
-
- WhitePedal: {
- DisplayName: White Pedal
- Tooltip: ""
- }
-
- WhiteWoodFlower: {
- DisplayName: White Wood Flower
- Tooltip: ""
- }
-
- YellowBellFlower: {
- DisplayName: Yellow Bell Flower
- Tooltip: ""
- }
-
- TreePlacer: {
- DisplayName: Tree Placer
- Tooltip: ""
- }
-
- TwilightWood: {
- DisplayName: Twilight Wood
- Tooltip: ""
- }
-
- YggdrasilImpression: {
- DisplayName: Yggdrasil Impression
- Tooltip: ""
- }
-
- ChinesePartitionLamp: {
- DisplayName: Chinese Partition Lamp
- Tooltip: ""
- }
-
- ChineseStyleFloorLamp: {
- DisplayName: Chinese Style Floor Lamp
- Tooltip: ""
- }
-
- CyanVineBar: {
- DisplayName: Cyan Vine Bar
- Tooltip: ""
- }
-
- CyanVineOre: {
- DisplayName: Cyan Vine Ore
- Tooltip: ""
- }
-
- DoubleArmsChineseStreetLamp: {
- DisplayName: Double Arms Chinese Street Lamp
- Tooltip: ""
- }
-
- HangingSkyLantern: {
- DisplayName: Hanging Sky Lantern
- Tooltip: ""
- }
-
- HexagonalCeilingLamp: {
- DisplayName: Hexagonal Ceiling Lamp
- Tooltip: ""
- }
-
- ShoreMud: {
- DisplayName: Shore Mud
- Tooltip: ""
- }
-
- SideHangingLantern: {
- DisplayName: Side Hanging Lantern
- Tooltip: ""
- }
-
- SideHangingLantern_White: {
- DisplayName: Side Hanging Lantern_ White
- Tooltip: ""
- }
-
- StoneDragonScaleWood: {
- DisplayName: Stone Dragon Scale Wood
- Tooltip: ""
- }
-
- StoneDragonScaleWoodWall: {
- DisplayName: Stone Dragon Scale Wood Wall
- Tooltip: ""
- }
-
- StreetLantern: {
- DisplayName: Street Lantern
- Tooltip: ""
- }
-
- YellowDynastyShingles: {
- DisplayName: Yellow Dynasty Shingles
- Tooltip: ""
- }
-
- YggdrasilAmber: {
- DisplayName: Yggdrasil Amber
- Tooltip: ""
- }
-
- CyanVineAxe: {
- DisplayName: Cyan Vine Axe
- Tooltip: ""
- }
-
- CyanVineHammer: {
- DisplayName: Cyan Vine Hammer
- Tooltip: ""
- }
-
- CyanVinePickaxe: {
- DisplayName: Cyan Vine Pickaxe
- Tooltip: ""
- }
-
- CyanVineSword: {
- DisplayName: Cyan Vine Sword
- Tooltip: ""
- }
-
- CyanVineThrowingSpear: {
- DisplayName: Cyan Vine Throwing Spear
- Tooltip: ""
- }
-
- DragonScaleWood: {
- DisplayName: Dragon Scale Wood
- Tooltip: ""
- }
-
- DragonScaleWoodWall: {
- DisplayName: Dragon Scale Wood Wall
- Tooltip: ""
- }
-
- OldMoss: {
- DisplayName: Old Moss
- Tooltip: ""
- }
-
- YggdrasilDirt: {
- DisplayName: Yggdrasil Dirt
- Tooltip: ""
- }
-
- AcroporaSpear: {
- DisplayName: Acropora Spear
- Tooltip: ""
- }
-
- CyanWindGranite: {
- DisplayName: Cyan Wind Granite
- Tooltip: ""
- }
-
- BloodLightCrystal: {
- DisplayName: Blood Light Crystal
- Tooltip: ""
- }
-
- TrueDeathSickle: {
- DisplayName: True Death Sickle
- Tooltip: ""
- }
-
- LiftLamp: {
- DisplayName: Lift Lamp
- Tooltip: ""
- }
-
- LiftWinch: {
- DisplayName: Lift Winch
- Tooltip: ""
- }
-
- HardmodeItem: {
- DisplayName: Hardmode Item
+Items: {
+ VFXGenerator: {
+ DisplayName: V F X Generator
Tooltip: ""
}
- SightOfTile: {
- DisplayName: Sight Of Tile
+ AirTileItem: {
+ DisplayName: Air Tile Item
Tooltip: ""
}
- TestItem: {
- DisplayName: Test Item
+ AirWallItem: {
+ DisplayName: Air Wall Item
Tooltip: ""
}
}
-NPCs: {
- TuskKillEffect.DisplayName: Tusk Kill Effect
- TuskWall.DisplayName: Tusk Wall
- BloodTusk.DisplayName: Blood Tusk
- BloodyMouth1.DisplayName: Bloody Mouth1
- BloodyMouth2.DisplayName: Bloody Mouth2
- CrimsonTusk.DisplayName: Crimson Tusk
- CrimsonTusk1.DisplayName: Crimson Tusk1
- CrimsonTuskControlable.DisplayName: Crimson Tusk Controlable
- CrimsonTuskFireWork.DisplayName: Crimson Tusk Fire Work
- HugeMouth.DisplayName: Huge Mouth
- LargeTusk.DisplayName: Large Tusk
- LargeTusk2.DisplayName: Large Tusk2
- LittleMouth.DisplayName: Little Mouth
- LittleTusk.DisplayName: Little Tusk
- TuskCooling.DisplayName: Tusk Cooling
- TuskPoolWave.DisplayName: Tusk Pool Wave
- TuskRedLight.DisplayName: Tusk Red Light
- TuskWallLeft.DisplayName: Tusk Wall Left
- TuskWallRight.DisplayName: Tusk Wall Right
- TuskWave.DisplayName: Tusk Wave
- TuskWaveHuge.DisplayName: Tusk Wave Huge
- GlowingHeal.DisplayName: Glowing Heal
- BlackStarFruit.DisplayName: Black Star Fruit
- CentipedeHead.DisplayName: Centipede Head
- CentipedeBody.DisplayName: Centipede Body
- CentipedeTail.DisplayName: Centipede Tail
- Dendroid_normal.DisplayName: Dendroid_normal
- FireflyPiranha.DisplayName: Firefly Piranha
- FireflyPiranhaInfected.DisplayName: Firefly Piranha Infected
- FireflyPiranhaInfected_small.DisplayName: Firefly Piranha Infected_small
- FireflyPiranha_small.DisplayName: Firefly Piranha_small
- GlowingFirefly.DisplayName: Glowing Firefly
- LargeFireBulb.DisplayName: Large Fire Bulb
- LittleFireBulb.DisplayName: Little Fire Bulb
- Butterfly.DisplayName: Butterfly
- CorruptMoth.DisplayName: Corrupt Moth
- EvilPack.DisplayName: Evil Pack
- MothSummonEffect.DisplayName: Moth Summon Effect
- FloatLantern.DisplayName: Float Lantern
- RedPackBomber.DisplayName: Red Pack Bomber
- LanternGhostKing.DisplayName: Lantern Ghost King
- BlueCore.DisplayName: Blue Core
- FlamingDashCore.DisplayName: Flaming Dash Core
- GreenCore.DisplayName: Green Core
- RedCore.DisplayName: Red Core
- YellowCore.DisplayName: Yellow Core
-
- Acytaea: {
- DisplayName: Acytaea
-
- TownNPCMood: {
- Content: I am content.
- NoHome: I hate not having a home.
- FarFromHome: I am too far from home.
- LoveSpace: I love having so much space.
- DislikeCrowded: I dislike how crowded I am.
- HateCrowded: I hate how crowded I am.
- LikeNPC_Princess: I like {NPCName}.
- Princess_LovesNPC: I like {NPCName}.
- }
- }
-
- AcytaeaShadow.DisplayName: Acytaea Shadow
- AcytaeaShadow2.DisplayName: Acytaea Shadow2
- AcytaeaShadow3.DisplayName: Acytaea Shadow3
- FakeAcytaea.DisplayName: Fake Acytaea
- CyanOreBeetle.DisplayName: Cyan Ore Beetle
- SquamousShell.DisplayName: Squamous Shell
- TestNPC.DisplayName: Test N P C
-}
-
-Prefixes: {
- Accurate.DisplayName: Accurate
- Aimed.DisplayName: Aimed
-}
-
-Projectiles: {
- BloodGoldBayonet_Pro.DisplayName: Blood Gold Bayonet_ Pro
- BlueRibbonBayonet_Pro.DisplayName: Blue Ribbon Bayonet_ Pro
- CopperStabbingSword_Pro.DisplayName: Copper Stabbing Sword_ Pro
- DreamStar_Explosion.DisplayName: Dream Star_ Explosion
- DreamStar_Pro.DisplayName: Dream Star_ Pro
- EnchantedBayonet_Pro.DisplayName: Enchanted Bayonet_ Pro
- EternalNight_Pro.DisplayName: Eternal Night_ Pro
- GoldenStabbingSword_Pro.DisplayName: Golden Stabbing Sword_ Pro
- HolyBayonet_Pro.DisplayName: Holy Bayonet_ Pro
- IronStabbingSword_Pro.DisplayName: Iron Stabbing Sword_ Pro
- LeadStabbingSword_Pro.DisplayName: Lead Stabbing Sword_ Pro
- PlatinumStabbingSword_Pro.DisplayName: Platinum Stabbing Sword_ Pro
- PrisonFireBayonet_Pro.DisplayName: Prison Fire Bayonet_ Pro
- RedRibbonBayonet_Pro.DisplayName: Red Ribbon Bayonet_ Pro
- RottenGoldBayonet_Mark.DisplayName: Rotten Gold Bayonet_ Mark
- RottenGoldBayonet_Pro.DisplayName: Rotten Gold Bayonet_ Pro
- RottenGoldBayonet_Slash.DisplayName: Rotten Gold Bayonet_ Slash
- SilverStabbingSword_Pro.DisplayName: Silver Stabbing Sword_ Pro
- TinStabbingSword_Pro.DisplayName: Tin Stabbing Sword_ Pro
- TungstenStabbingSword_Pro.DisplayName: Tungsten Stabbing Sword_ Pro
- VegetationBayonet_Pro.DisplayName: Vegetation Bayonet_ Pro
- YoenLeZed_Pro.DisplayName: Yoen Le Zed_ Pro
- FryingPan.DisplayName: Frying Pan
- ButterflyDreamFriendly.DisplayName: Butterfly Dream Friendly
- ButterflyDream.DisplayName: Butterfly Dream
- DashingLightEff.DisplayName: Dashing Light Eff
- VortexVanquisher.DisplayName: Vortex Vanquisher
- VortexVanquisher2.DisplayName: Vortex Vanquisher2
- VortexVanquisher3.DisplayName: Vortex Vanquisher3
- VortexVanquisherThump.DisplayName: Vortex Vanquisher Thump
- GoldShield.DisplayName: Gold Shield
- StonePost.DisplayName: Stone Post
- CrimsonTuskProj.DisplayName: Crimson Tusk Proj
- CrimsonTuskProjGra.DisplayName: Crimson Tusk Proj Gra
- EarthTusk.DisplayName: Earth Tusk
- EarthTuskHostile.DisplayName: Earth Tusk Hostile
- TuskCrack.DisplayName: Tusk Crack
- TuskCurse.DisplayName: Tusk Curse
- TuskSpice.DisplayName: Tusk Spice
- TuskSpiceBlack.DisplayName: Tusk Spice Black
- TuskSpicePro.DisplayName: Tusk Spice Pro
- Tusk.DisplayName: Tusk
- BloodyBoneYoyo.DisplayName: Bloody Bone Yoyo
- LittleTusk.DisplayName: Little Tusk
- LittleTusk0.DisplayName: Little Tusk0
- SpineGun.DisplayName: Spine Gun
- SplieSpineBullet.DisplayName: Splie Spine Bullet
- ToothMagic.DisplayName: Tooth Magic
- ToothMagicBall.DisplayName: Tooth Magic Ball
- ToothMagicHit.DisplayName: Tooth Magic Hit
- ToothMagicSplit.DisplayName: Tooth Magic Split
- ToothMagicSplit2.DisplayName: Tooth Magic Split2
- ToothSpear.DisplayName: Tooth Spear
- Tusk0.DisplayName: Tusk0
- TuskArrow.DisplayName: Tusk Arrow
- TuskSpear3.DisplayName: Tusk Spear3
- TuskSpear4.DisplayName: Tusk Spear4
- TuskSummon.DisplayName: Tusk Summon
- BeadShakeWave.DisplayName: Bead Shake Wave
- BlackCorruptRain.DisplayName: Black Corrupt Rain
- BlackCorruptRain3.DisplayName: Black Corrupt Rain3
- BlackCorruptRain3Friendly.DisplayName: Black Corrupt Rain3 Friendly
- BlackCorruptRainFriendly.DisplayName: Black Corrupt Rain Friendly
- BlueMissil.DisplayName: Blue Missil
- BlueMissilFriendly.DisplayName: Blue Missil Friendly
- BombShakeWave.DisplayName: Bomb Shake Wave
- CorMoth4DProj.DisplayName: Cor Moth4 D Proj
- CorruptDust.DisplayName: Corrupt Dust
- DarkEffect.DisplayName: Dark Effect
- DarkFan.DisplayName: Dark Fan
- DarkFanFly.DisplayName: Dark Fan Fly
- DreamWeaver.DisplayName: Dream Weaver
- EvilChrysalis.DisplayName: Evil Chrysalis
- EvilChrysalisRightClick.DisplayName: Evil Chrysalis Right Click
- FanHit.DisplayName: Fan Hit
- FlowLightMissile.DisplayName: Flow Light Missile
- FruitBomb.DisplayName: Fruit Bomb
- GlowBeadGun.DisplayName: Glow Bead Gun
- GlowBeadGunShootFlame.DisplayName: Glow Bead Gun Shoot Flame
- GlowingButterfly.DisplayName: Glowing Butterfly
- GlowMoth.DisplayName: Glow Moth
- GlowStar.DisplayName: Glow Star
- GlowStarExplosion.DisplayName: Glow Star Explosion
- GlowWoodSword.DisplayName: Glow Wood Sword
- MissileProj.DisplayName: Missile Proj
- MissileProjHostile.DisplayName: Missile Proj Hostile
- MothArrow.DisplayName: Moth Arrow
- MothBall.DisplayName: Moth Ball
- MothGrey.DisplayName: Moth Grey
- MothMagicArray.DisplayName: Moth Magic Array
- MothYoyoProjectile.DisplayName: Moth Yoyo Projectile
- MothYoyoSub.DisplayName: Moth Yoyo Sub
- NavyThunder.DisplayName: Navy Thunder
- NavyThunderBomb.DisplayName: Navy Thunder Bomb
- PhantomMoth.DisplayName: Phantom Moth
- PhosphorescenceBullet.DisplayName: Phosphorescence Bullet
- PhosphorescenceGun.DisplayName: Phosphorescence Gun
- ScaleWingBladeProj.DisplayName: Scale Wing Blade Proj
- ShadowWingBow.DisplayName: Shadow Wing Bow
- StaffOfCorruptDust.DisplayName: Staff Of Corrupt Dust
- LilyHarpNote.DisplayName: Lily Harp Note
- LilyHarpNoteKill.DisplayName: Lily Harp Note Kill
- LilyHarpProj.DisplayName: Lily Harp Proj
- LilyHarpWave.DisplayName: Lily Harp Wave
- VineProj.DisplayName: Vine Proj
- VineProj2.DisplayName: Vine Proj2
- CloudBall.DisplayName: Cloud Ball
- MagicHit.DisplayName: Magic Hit
- AshBone.DisplayName: Ash Bone
- XmasWhip.DisplayName: Xmas Whip
- AmbiguousLine.DisplayName: Ambiguous Line
- AmbiguousNight.DisplayName: Ambiguous Night
- AmbiguousNightAmmo.DisplayName: Ambiguous Night Ammo
- AmbiguousNightHit.DisplayName: Ambiguous Night Hit
- AmethystBead.DisplayName: Amethyst Bead
- AmethystSlingshot.DisplayName: Amethyst Slingshot
- BorealWoodSlingshot.DisplayName: Boreal Wood Slingshot
- CactusSlingShot.DisplayName: Cactus Sling Shot
- DiamondBead.DisplayName: Diamond Bead
- DiamondSlingshot.DisplayName: Diamond Slingshot
- EbonwoodSlingshot.DisplayName: Ebonwood Slingshot
- EmeraldBead.DisplayName: Emerald Bead
- EmeraldSlingshot.DisplayName: Emerald Slingshot
- GelBall.DisplayName: Gel Ball
- GelSlingshot.DisplayName: Gel Slingshot
- GlowSporeBead.DisplayName: Glow Spore Bead
- JungleSlingshot.DisplayName: Jungle Slingshot
- JungleSlingshotHit.DisplayName: Jungle Slingshot Hit
- KSSlingshotHit.DisplayName: K S Slingshot Hit
- KSSlingshotHitPink.DisplayName: K S Slingshot Hit Pink
- NormalAmmo.DisplayName: Normal Ammo
- NormalHit.DisplayName: Normal Hit
- PalmWoodSlingshot.DisplayName: Palm Wood Slingshot
- PearlwoodSlingshot.DisplayName: Pearlwood Slingshot
- RichMahoganySlingshot.DisplayName: Rich Mahogany Slingshot
- RubyBead.DisplayName: Ruby Bead
- RubySlingshot.DisplayName: Ruby Slingshot
- SapphireBead.DisplayName: Sapphire Bead
- SapphireSlingshot.DisplayName: Sapphire Slingshot
- ShadewoodSlingShot.DisplayName: Shadewood Sling Shot
- StarAmmo.DisplayName: Star Ammo
- StarSlingshot.DisplayName: Star Slingshot
- TopazBead.DisplayName: Topaz Bead
- TopazSlingshot.DisplayName: Topaz Slingshot
- WoodSlingshot.DisplayName: Wood Slingshot
- ComingGhost.DisplayName: Coming Ghost
- ComingGhost2.DisplayName: Coming Ghost2
- GhostHit.DisplayName: Ghost Hit
- GoldRound.DisplayName: Gold Round
- GoldRoundYoyo.DisplayName: Gold Round Yoyo
- MeleeHit.DisplayName: Melee Hit
- MeleeHit2.DisplayName: Melee Hit2
- Sunflower.DisplayName: Sunflower
- SunFlowerpetal.DisplayName: Sun Flowerpetal
- World.DisplayName: World
- WorldHit.DisplayName: World Hit
- Hepuyuan.DisplayName: Hepuyuan
- HepuyuanDown.DisplayName: Hepuyuan Down
- HepuyuanShake.DisplayName: Hepuyuan Shake
- HepuyuanSpice.DisplayName: Hepuyuan Spice
- XiaoBlackWave.DisplayName: Xiao Black Wave
- XiaoHit.DisplayName: Xiao Hit
- AdamantiteClub.DisplayName: Adamantite Club
- BorealWoodClub.DisplayName: Boreal Wood Club
- CactusClub.DisplayName: Cactus Club
- ChlorophyteClub.DisplayName: Chlorophyte Club
- ChlorophyteClub_fly.DisplayName: Chlorophyte Club_fly
- ChlorophyteClub_VFX.DisplayName: Chlorophyte Club_ V F X
- CobaltClub.DisplayName: Cobalt Club
- CopperClub.DisplayName: Copper Club
- CorruptClub.DisplayName: Corrupt Club
- CrimsonClub.DisplayName: Crimson Club
- CrystalClub.DisplayName: Crystal Club
- CrystalClub_fly.DisplayName: Crystal Club_fly
- CurseClub.DisplayName: Curse Club
- CurseClub_fly.DisplayName: Curse Club_fly
- EbonwoodClub.DisplayName: Ebonwood Club
- GoldClub.DisplayName: Gold Club
- IchorClub.DisplayName: Ichor Club
- IchorClub_fly.DisplayName: Ichor Club_fly
- IronClub.DisplayName: Iron Club
- LeadClub.DisplayName: Lead Club
- MeteorClub.DisplayName: Meteor Club
- MithrilClub.DisplayName: Mithril Club
- OrichalcumClub.DisplayName: Orichalcum Club
- PalladiumClub.DisplayName: Palladium Club
- PalmWoodClub.DisplayName: Palm Wood Club
- PearlwoodClub.DisplayName: Pearlwood Club
- PlatinumClub.DisplayName: Platinum Club
- RichMahoganyClub.DisplayName: Rich Mahogany Club
- ShadewoodClub.DisplayName: Shadewood Club
- SilverClub.DisplayName: Silver Club
- SpikeClub.DisplayName: Spike Club
- StarDancer.DisplayName: Star Dancer
- TinClub.DisplayName: Tin Club
- TitaniumClub.DisplayName: Titanium Club
- TungstenClub.DisplayName: Tungsten Club
- WoodenClub.DisplayName: Wooden Club
- BoneFeather.DisplayName: Bone Feather
- EndlessCurseFlame.DisplayName: Endless Curse Flame
- FireFeather.DisplayName: Fire Feather
- FreezeFeather.DisplayName: Freeze Feather
- ThunderBall.DisplayName: Thunder Ball
- ThunderBall2.DisplayName: Thunder Ball2
- ThunderBallToNPC.DisplayName: Thunder Ball To N P C
- FreezeFeatherMagicArray.DisplayName: Freeze Feather Magic Array
- FreezeFeatherMagicBook.DisplayName: Freeze Feather Magic Book
- FreezeShoot.DisplayName: Freeze Shoot
- GiantFreezeFeather.DisplayName: Giant Freeze Feather
- GiantFreezeFeatherExplosion.DisplayName: Giant Freeze Feather Explosion
- FireFeatherMagicArray.DisplayName: Fire Feather Magic Array
- FireFeatherMagicBook.DisplayName: Fire Feather Magic Book
- FlameShoot.DisplayName: Flame Shoot
- GiantFireFeather.DisplayName: Giant Fire Feather
- GiantFireFeatherExplosion.DisplayName: Giant Fire Feather Explosion
- FlowerPetalPurple.DisplayName: Flower Petal Purple
- PurpleBallEffect.DisplayName: Purple Ball Effect
- FixCoinCrit1.DisplayName: Fix Coin Crit1
- FixCoinCrit2.DisplayName: Fix Coin Crit2
- FixCoinCrit3.DisplayName: Fix Coin Crit3
- FixCoinCrit4.DisplayName: Fix Coin Crit4
- FixCoinCrit5.DisplayName: Fix Coin Crit5
- FixCoinDamage1.DisplayName: Fix Coin Damage1
- FixCoinDamage2.DisplayName: Fix Coin Damage2
- FixCoinDamage3.DisplayName: Fix Coin Damage3
- FixCoinDamage4.DisplayName: Fix Coin Damage4
- FixCoinDamage5.DisplayName: Fix Coin Damage5
- FixCoinDefense1.DisplayName: Fix Coin Defense1
- FixCoinDefense2.DisplayName: Fix Coin Defense2
- FixCoinDefense3.DisplayName: Fix Coin Defense3
- FixCoinDefense4.DisplayName: Fix Coin Defense4
- FixCoinDefense5.DisplayName: Fix Coin Defense5
- FixCoinMelee1.DisplayName: Fix Coin Melee1
- FixCoinMelee2.DisplayName: Fix Coin Melee2
- FixCoinMelee3.DisplayName: Fix Coin Melee3
- FixCoinSpeed1.DisplayName: Fix Coin Speed1
- FixCoinSpeed2.DisplayName: Fix Coin Speed2
- FixCoinSpeed3.DisplayName: Fix Coin Speed3
- IchorRing.DisplayName: Ichor Ring
- NewWaterBolt.DisplayName: New Water Bolt
- WaterBoltArray.DisplayName: Water Bolt Array
- WaterBoltBook.DisplayName: Water Bolt Book
- WaterTeleport.DisplayName: Water Teleport
- HurricaneMask.DisplayName: Hurricane Mask
- RazorbladeTyphoonArray.DisplayName: Razorblade Typhoon Array
- RazorbladeTyphoonBook.DisplayName: Razorblade Typhoon Book
- TyphoonII.DisplayName: Typhoon I I
- MagnetSphereArray.DisplayName: Magnet Sphere Array
- MagnetSphereBook.DisplayName: Magnet Sphere Book
- MagnetSphereHit.DisplayName: Magnet Sphere Hit
- MagnetSphereII.DisplayName: Magnet Sphere I I
- MagnetSphereLighting.DisplayName: Magnet Sphere Lighting
- LunarFlareArray.DisplayName: Lunar Flare Array
- LunarFlareBook.DisplayName: Lunar Flare Book
- LunarFlareHit.DisplayName: Lunar Flare Hit
- LunarFlareII.DisplayName: Lunar Flare I I
- StarProj.DisplayName: Star Proj
- GoldenShowerArray.DisplayName: Golden Shower Array
- GoldenShowerBomb.DisplayName: Golden Shower Bomb
- GoldenShowerBook.DisplayName: Golden Shower Book
- GoldenShowerII.DisplayName: Golden Shower I I
- DreamWeaverBook.DisplayName: Dream Weaver Book
- DreamWeaverII.DisplayName: Dream Weaver I I
- DemoHit.DisplayName: Demo Hit
- DemonScytheArray.DisplayName: Demon Scythe Array
- DemonScytheBook.DisplayName: Demon Scythe Book
- DemonScythePlus.DisplayName: Demon Scythe Plus
- DemonScythePlusCrack.DisplayName: Demon Scythe Plus Crack
- DemoSpark.DisplayName: Demo Spark
- CursedFlameHit.DisplayName: Cursed Flame Hit
- CursedFlamesArray.DisplayName: Cursed Flames Array
- CursedFlamesBook.DisplayName: Cursed Flames Book
- CursedFlamesII.DisplayName: Cursed Flames I I
- CrystalStormArray.DisplayName: Crystal Storm Array
- CrystalStormBook.DisplayName: Crystal Storm Book
- CrystalStormII.DisplayName: Crystal Storm I I
- CrystalWind.DisplayName: Crystal Wind
- LargeCrystal.DisplayName: Large Crystal
- Storm.DisplayName: Storm
- BoneSpike.DisplayName: Bone Spike
- BookofSkullsArray.DisplayName: Bookof Skulls Array
- BookofSkullsBook.DisplayName: Bookof Skulls Book
- SkullHand.DisplayName: Skull Hand
- SkullII.DisplayName: Skull I I
- BlackHole.DisplayName: Black Hole
- BloodLampProj.DisplayName: Blood Lamp Proj
- LBloodEffect.DisplayName: L Blood Effect
- LBloodEffectGra.DisplayName: L Blood Effect Gra
- LMeteor.DisplayName: L Meteor
- RainbowWave.DisplayName: Rainbow Wave
- DarkLantern.DisplayName: Dark Lantern
- DarkLantern3.DisplayName: Dark Lantern3
- DarkLanternBomb2.DisplayName: Dark Lantern Bomb2
- DarkLanternBombExplosion.DisplayName: Dark Lantern Bomb Explosion
- DarkLanternBombExplosion_II.DisplayName: Dark Lantern Bomb Explosion_ I I
- ExplodeLantern.DisplayName: Explode Lantern
- floatLantern.DisplayName: float Lantern
- floatLantern2.DisplayName: float Lantern2
- floatLantern3.DisplayName: float Lantern3
- floatLantern4.DisplayName: float Lantern4
- floatLantern5.DisplayName: float Lantern5
- GoldLantern.DisplayName: Gold Lantern
- GoldLanternLine.DisplayName: Gold Lantern Line
- GoldLanternLine2.DisplayName: Gold Lantern Line2
- GoldLanternLine3.DisplayName: Gold Lantern Line3
- GoldLanternLine4.DisplayName: Gold Lantern Line4
- GoldLanternLine5.DisplayName: Gold Lantern Line5
- GoldLanternLine6.DisplayName: Gold Lantern Line6
- GoldLanternLine7.DisplayName: Gold Lantern Line7
- GoldLanternLine8.DisplayName: Gold Lantern Line8
- GoldLanternRay.DisplayName: Gold Lantern Ray
- GoldLanternStar.DisplayName: Gold Lantern Star
- Redlight.DisplayName: Redlight
- StrikePlayer.DisplayName: Strike Player
- BlueFlame0.DisplayName: Blue Flame0
- BlueFlame0Little.DisplayName: Blue Flame0 Little
- BlueFlame0LittleSoon.DisplayName: Blue Flame0 Little Soon
- BlueFlame1Boom.DisplayName: Blue Flame1 Boom
- BlueStarTrail.DisplayName: Blue Star Trail
- BrownFlame0.DisplayName: Brown Flame0
- BrownFlame0Little.DisplayName: Brown Flame0 Little
- GoldDashLine.DisplayName: Gold Dash Line
- GreenFlame0.DisplayName: Green Flame0
- GreenFlame0Little.DisplayName: Green Flame0 Little
- GreenFlame0Split.DisplayName: Green Flame0 Split
- GreenFlame1Split.DisplayName: Green Flame1 Split
- ImmuneCircle.DisplayName: Immune Circle
- PinkFlame0.DisplayName: Pink Flame0
- PinkFlame0Little.DisplayName: Pink Flame0 Little
- PurpleFlame0.DisplayName: Purple Flame0
- PurpleFlame0Little.DisplayName: Purple Flame0 Little
- PurpleGreenFlame0.DisplayName: Purple Green Flame0
- PurpleGreenFlame0Little.DisplayName: Purple Green Flame0 Little
- RedFlame0.DisplayName: Red Flame0
- RedFlame0Little.DisplayName: Red Flame0 Little
- RedFlame0Split.DisplayName: Red Flame0 Split
- RedFlame1Split.DisplayName: Red Flame1 Split
- RedFlame2Split.DisplayName: Red Flame2 Split
- YellowFlame0.DisplayName: Yellow Flame0
- YellowFlame0Little.DisplayName: Yellow Flame0 Little
- YellowFlame0LittleShine.DisplayName: Yellow Flame0 Little Shine
- YellowFlame0Shine.DisplayName: Yellow Flame0 Shine
- YellowToRedFlame0Little.DisplayName: Yellow To Red Flame0 Little
- AcytaeaArrow.DisplayName: Acytaea Arrow
- AcytaeaArrow2.DisplayName: Acytaea Arrow2
- AcytaeaArrow3.DisplayName: Acytaea Arrow3
- AcytaeaArrowGra.DisplayName: Acytaea Arrow Gra
- AcytaeaBow.DisplayName: Acytaea Bow
- AcytaeaBow2.DisplayName: Acytaea Bow2
- AcytaeaCenterBow.DisplayName: Acytaea Center Bow
- AcytaeaEffect.DisplayName: Acytaea Effect
- AcytaeaEffectUp.DisplayName: Acytaea Effect Up
- AcytaeaLaser.DisplayName: Acytaea Laser
- AcytaeaLaserBall.DisplayName: Acytaea Laser Ball
- AcytaeaLaserLight.DisplayName: Acytaea Laser Light
- AcytaeaLight.DisplayName: Acytaea Light
- AcytaeaMagicBook.DisplayName: Acytaea Magic Book
- AcytaeaTornado.DisplayName: Acytaea Tornado
- AcytaeaTornado2.DisplayName: Acytaea Tornado2
- AcytaeaTornado3.DisplayName: Acytaea Tornado3
- AcytaeaTornado4.DisplayName: Acytaea Tornado4
- AcytaeaTornado5.DisplayName: Acytaea Tornado5
- AcytaeaTornadoHit.DisplayName: Acytaea Tornado Hit
- AcytaeaWarningArrow.DisplayName: Acytaea Warning Arrow
- BloodBlade.DisplayName: Blood Blade
- BloodBlade2.DisplayName: Blood Blade2
- BloodBladeShadow.DisplayName: Blood Blade Shadow
- BrokenAcytaea.DisplayName: Broken Acytaea
- BrokenAcytaea2.DisplayName: Broken Acytaea2
- Metero.DisplayName: Metero
- Metero2.DisplayName: Metero2
- Metero3.DisplayName: Metero3
- Metero4.DisplayName: Metero4
- MeteroFri.DisplayName: Metero Fri
- playerHit.DisplayName: player Hit
- CactusBallProj.DisplayName: Cactus Ball Proj
- CactusBallSpike.DisplayName: Cactus Ball Spike
- CyanVineThrowingSpear.DisplayName: Cyan Vine Throwing Spear
- AcroporaSpear.DisplayName: Acropora Spear
- AcroporaThumpEff.DisplayName: Acropora Thump Eff
- TrueDeathSickle.DisplayName: True Death Sickle
- TrueDeathSickleHit.DisplayName: True Death Sickle Hit
- SightOfTileProj.DisplayName: Sight Of Tile Proj
- SightOfTileProjRead.DisplayName: Sight Of Tile Proj Read
-}
-
Configs: {
EverglowConfig: {
DisplayName: Everglow Config
@@ -2974,80 +68,6 @@ Configs: {
TuskFighting.Label: Original
OldTuskFighting.Label: Old
}
-
- FogConfigs: {
- DisplayName: Fog Configs
-
- EnableScattering: {
- Label: 开启雾效
- Tooltip: 是否开启参与介质散射
- }
-
- EnableLightUpload: {
- Label: 【性能测试】开启光源数据
- Tooltip: 是否启用发光体数据上传(CPU到GPU)
- }
-
- MaxBloomRadius: {
- Label: 模糊半径
- Tooltip: 光效的最大溢出半径,最终半径是以2为底的指数,越大越影响性能
- }
-
- BloomIntensity: {
- Label: 光效强度
- Tooltip: 光效的强度,用于放大亮度
- }
-
- OffscreenTiles: {
- Label: 离屏物块渲染数量
- Tooltip: 光效需要计算超出屏幕的物块数量
- }
-
- LightLuminanceThreashold: {
- Label: 光源阈值
- Tooltip: 可以调整原版点亮物块的光源阈值
- }
-
- GaussianKernel: {
- Label: 是否开启高斯卷积核
- Tooltip: 更柔和的效果,但是性能较差
- }
-
- FogAbsorptionR: {
- Label: 雾吸收率(R)
- Tooltip: 雾吸收红色通道直接光的比率,越大则越暗淡
- }
-
- FogAbsorptionG: {
- Label: 雾吸收率(G)
- Tooltip: 雾吸收绿色通道直接光的比率,越大则越暗淡
- }
-
- FogAbsorptionB: {
- Label: 雾吸收率(B)
- Tooltip: 雾吸收蓝色通道直接光的比率,越大则越暗淡
- }
-
- FogScatterWithDistance: {
- Label: 扩散率随距离增大
- Tooltip: 是否让散射效果随着距离增大而增大
- }
-
- FogBloomRate: {
- Label: 雾散射扩散率
- Tooltip: 散射光的扩散比率
- }
-
- FogBloomAbsorptionFactor: {
- Label: 雾散射能见度影响系数
- Tooltip: 散射光受到能见度影响的比率,0为不受能见度影响,1完全受能见度影响
- }
-
- EnableTemporalInterp: {
- Label: 开启Temporal插值
- Tooltip: 是否允许光照结果进行帧间插值来平滑
- }
- }
}
Config: {
diff --git a/Sources/Everglow/Module.Build.props b/Sources/Everglow/Module.Build.props
index 3ee36aaab..37f541dc7 100644
--- a/Sources/Everglow/Module.Build.props
+++ b/Sources/Everglow/Module.Build.props
@@ -1,7 +1,6 @@
-
-
+ Example
$(DefineConstants);$(Modules)
diff --git a/Sources/Modules/Example/Everglow.Example.csproj b/Sources/Modules/Example/Everglow.Example.csproj
index 3eb1642e0..ba938f7b3 100644
--- a/Sources/Modules/Example/Everglow.Example.csproj
+++ b/Sources/Modules/Example/Everglow.Example.csproj
@@ -1,6 +1,3 @@
-
-
-
\ No newline at end of file
diff --git a/Sources/Modules/Example/PhysicsDemo.cs b/Sources/Modules/Example/PhysicsDemo.cs
index 3dcb32ff0..51b78d573 100644
--- a/Sources/Modules/Example/PhysicsDemo.cs
+++ b/Sources/Modules/Example/PhysicsDemo.cs
@@ -219,7 +219,7 @@ public void ReStart()
rigidb.AngularDrag = 0;
rigidb.Drag = 0;
rigidb.Stiffness = -1;
- rigidb.Friction = -1;
+ rigidb.Friction = 0;
_realSimulation.AddPhysicsObject(_dummyPlayer);
_realSimulation.Initialize();
}
From b0de72fc419a40f4c65542adfa3b5227470ea867 Mon Sep 17 00:00:00 2001
From: CXUtk <2237367067@qq.com>
Date: Wed, 19 Jul 2023 22:15:41 -0700
Subject: [PATCH 06/13] update physics engine
---
.../Everglow.Core/DataStructures/UnionFind.cs | 53 +++
.../Physics/PBEngine/Collision/AABB.cs | 53 ++-
.../Collision/BroadPhase/BVHDetect.cs | 175 +++++++
.../Collision/BroadPhase/BruteForceDetect.cs | 91 +++-
.../Collision/BroadPhase/CollisionGraph.cs | 4 +-
.../Collision/BroadPhase/HashGridMethod.cs | 158 +++++++
.../Collision/BroadPhase/IBroadPhase.cs | 20 +-
.../Collision/BroadPhase/Structure/BVH.cs | 400 ++++++++++++++++
.../Structure/MultiLevelHashGrid.cs | 432 ++++++++++++++++++
.../Collision/BroadPhase/SweepAndPrune.cs | 222 +++++----
.../Collision/Colliders/BoxCollider.cs | 79 ++--
.../Collision/Colliders/CapsuleCollider.cs | 267 +++++++++++
.../Collision/Colliders/SphereCollider.cs | 49 +-
.../PBEngine/Collision/CollisionEvent2D.cs | 2 +
.../Physics/PBEngine/Constrains/Constrain.cs | 3 +-
.../PBEngine/Constrains/JointConstrain.cs | 13 +-
.../PBEngine/Constrains/SpringConstrain.cs | 162 ++++---
.../GameInteraction/TileCollisionUtils.cs | 136 +++++-
.../Physics/PBEngine/GeometryUtils.cs | 429 +++++++++++++++--
.../Physics/PBEngine/PhysicsObject.cs | 47 +-
.../Physics/PBEngine/PhysicsSimulation.cs | 388 +++++++++++++---
.../PlayGround/Contact/ContactPlayGround1.cs | 51 +++
.../Physics/PBEngine/RigidBody2D.cs | 400 ++++++++++------
Sources/Modules/Example/PhysicsDemo.cs | 371 +++++++++++++--
Sources/Modules/Example/RigidBodyDisplay.cs | 10 +-
25 files changed, 3511 insertions(+), 504 deletions(-)
create mode 100644 Sources/Everglow.Core/DataStructures/UnionFind.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BVHDetect.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/HashGridMethod.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/Structure/BVH.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/Structure/MultiLevelHashGrid.cs
create mode 100644 Sources/Everglow.Core/Physics/PBEngine/Collision/Colliders/CapsuleCollider.cs
diff --git a/Sources/Everglow.Core/DataStructures/UnionFind.cs b/Sources/Everglow.Core/DataStructures/UnionFind.cs
new file mode 100644
index 000000000..2bf110579
--- /dev/null
+++ b/Sources/Everglow.Core/DataStructures/UnionFind.cs
@@ -0,0 +1,53 @@
+namespace Everglow.Commons.DataStructures;
+
+public class UnionFind
+{
+ private int[] parent;
+ private int[] rank;
+
+ public UnionFind(int size)
+ {
+ parent = new int[size];
+ rank = new int[size];
+
+ for (int i = 0; i < size; i++)
+ {
+ parent[i] = i;
+ rank[i] = 0;
+ }
+ }
+
+ public int Find(int x)
+ {
+ if (parent[x] != x)
+ {
+ parent[x] = Find(parent[x]);
+ }
+ return parent[x];
+ }
+
+ public void Union(int x, int y)
+ {
+ int rootX = Find(x);
+ int rootY = Find(y);
+
+ if (rootX == rootY)
+ {
+ return;
+ }
+
+ if (rank[rootX] < rank[rootY])
+ {
+ parent[rootX] = rootY;
+ }
+ else if (rank[rootX] > rank[rootY])
+ {
+ parent[rootY] = rootX;
+ }
+ else
+ {
+ parent[rootY] = rootX;
+ rank[rootX]++;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs
index 6ced81e82..e3813cd2c 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/AABB.cs
@@ -6,15 +6,66 @@
namespace Everglow.Commons.Physics.PBEngine.Collision
{
- public struct AABB
+ public struct AABB
{
public Vector2 MinPoint;
public Vector2 MaxPoint;
+ public AABB()
+ {
+ MinPoint = new Vector2(float.PositiveInfinity);
+ MaxPoint = new Vector2(float.NegativeInfinity);
+ }
+
+ public AABB(Vector2 minP, Vector2 maxP)
+ {
+ MinPoint = minP;
+ MaxPoint = maxP;
+ }
+
+ public Vector2 Center
+ {
+ get => (MaxPoint + MinPoint) / 2;
+ }
+
public bool Intersects(in AABB other)
{
return Math.Max(MinPoint.X, other.MinPoint.X) <= Math.Min(MaxPoint.X, other.MaxPoint.X)
&& Math.Max(MinPoint.Y, other.MinPoint.Y) <= Math.Min(MaxPoint.Y, other.MaxPoint.Y);
}
+
+ public AABB Move(Vector2 v)
+ {
+ return new AABB() { MinPoint = MinPoint + v, MaxPoint = MaxPoint + v };
+ }
+
+ public AABB Merge(in AABB other)
+ {
+ return new AABB() { MinPoint = Vector2.Min(MinPoint, other.MinPoint), MaxPoint = Vector2.Max(MaxPoint, other.MaxPoint) };
+ }
+
+ public void MergeWith(in AABB other)
+ {
+ MinPoint = Vector2.Min(MinPoint, other.MinPoint);
+ MaxPoint = Vector2.Max(MaxPoint, other.MaxPoint);
+ }
+
+ public double GetArea()
+ {
+ double w = MaxPoint.X - MinPoint.X;
+ double h = MaxPoint.Y - MinPoint.Y;
+ return w * h;
+ }
+
+ public bool CompletelyInside(in AABB other)
+ {
+ return other.MinPoint.X <= MinPoint.X && other.MaxPoint.X >= MaxPoint.X
+ && other.MinPoint.Y <= MinPoint.Y && other.MaxPoint.Y >= MaxPoint.Y;
+ }
+
+ public AABB EnLarge(float size)
+ {
+ return new AABB() { MinPoint = MinPoint - new Vector2(size), MaxPoint = MaxPoint + new Vector2(size) };
+ }
}
}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BVHDetect.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BVHDetect.cs
new file mode 100644
index 000000000..1526a23a5
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BVHDetect.cs
@@ -0,0 +1,175 @@
+using Everglow.Commons.Physics.PBEngine;
+using Everglow.Commons.Physics.PBEngine.Collision;
+using Everglow.Commons.Physics.PBEngine.Collision.BroadPhase;
+using Everglow.Commons.Physics.PBEngine.Collision.BroadPhase.Structure;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria.GameContent;
+using Terraria;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
+{
+ ///
+ /// 使用BVH辅助加速碰撞检测
+ ///
+ public class BVHDetect : IBroadPhase
+ {
+ private List _colliders;
+ private Dictionary> _groups;
+ private Dictionary _bvhForGroup;
+ public BVHDetect(CollisionGraph graph) : base(graph)
+ {
+ _colliders = new List();
+ _groups = new Dictionary>();
+ _bvhForGroup = new Dictionary();
+ }
+
+ private void GroupInnerDetection(string name,
+ List> collisionResults)
+ {
+ var pairs = _bvhForGroup[name].QueryPairs();
+ foreach (var pair in pairs)
+ {
+ collisionResults.Add(new KeyValuePair(_colliders[pair.Key],
+ _colliders[pair.Value]));
+ }
+ }
+
+ private void GroupOuterDetection(string groupA, string groupB,
+ List> collisionResults)
+ {
+ var groupAEntries = _groups[groupA];
+ var groupBBVH = _bvhForGroup[groupB];
+ for (int i = 0; i < groupAEntries.Count; i++)
+ {
+ foreach (var id in groupBBVH.QueryRange(groupAEntries[i].BoundingBox))
+ {
+ if (groupAEntries[i].IsDynamic || _colliders[id].ParentObject.RigidBody.MovementType == MovementType.Player ||
+ _colliders[id].ParentObject.RigidBody.MovementType == MovementType.Dynamic)
+ {
+ collisionResults.Add(new KeyValuePair(_colliders[groupAEntries[i].ColliderId],
+ _colliders[id]));
+ }
+ }
+ }
+ }
+
+ public override List> GetCollisionPairs(float deltaTime)
+ {
+ List> finalPairs = new List>();
+ foreach (var group in _groups)
+ {
+ var thisgroup = _groups[group.Key];
+ if (_collisionGraph.Graph.ContainsKey(group.Key))
+ {
+ foreach (var dual in _collisionGraph.Graph[group.Key])
+ {
+ if (dual == group.Key)
+ {
+ GroupInnerDetection(group.Key, finalPairs);
+ continue;
+ }
+ if (!_groups.ContainsKey(dual))
+ continue;
+ GroupOuterDetection(group.Key, dual, finalPairs);
+ }
+ }
+ }
+ return finalPairs;
+ }
+
+ public override void Prepare(List objects, float deltaTime)
+ {
+ _colliders.Clear();
+ _colliders.EnsureCapacity(objects.Count);
+ _groups.Clear();
+ _bvhForGroup.Clear();
+ for (int i = 0; i < objects.Count; i++)
+ {
+ var obj = objects[i];
+ _colliders.Add(obj.Collider);
+ var entry = new ColliderEntry()
+ {
+ ColliderId = i,
+ BoundingBox = obj.Collider.GetAABB(deltaTime),
+ IsDynamic = obj.RigidBody.MovementType == MovementType.Dynamic || obj.RigidBody.MovementType == MovementType.Player
+ };
+
+ if (_groups.ContainsKey(obj.Tag))
+ {
+ _groups[obj.Tag].Add(entry);
+ }
+ else
+ {
+ _groups.Add(obj.Tag, new List()
+ {
+ entry
+ });
+ }
+ }
+ foreach (var group in _groups)
+ {
+ _bvhForGroup.Add(group.Key, new BVH(group.Value));
+ }
+ }
+
+ public override List GetSingleCollision(AABB aabb, Vector2 velocity, float deltaTime, List targetTags)
+ {
+ List colliders = new List();
+ foreach (var tag in targetTags)
+ {
+ if (!_groups.ContainsKey(tag))
+ {
+ continue;
+ }
+ var bvhThisGroup = _bvhForGroup[tag];
+
+ foreach (var id in bvhThisGroup.QueryRange(aabb))
+ {
+ colliders.Add(_colliders[id]);
+ }
+ }
+ return colliders;
+ }
+
+ public override void DrawDebugInfo(SpriteBatch sb)
+ {
+ if (!_groups.ContainsKey("Default"))
+ return;
+ //var data = _bvhForGroup["Default"].GetProfilingData();
+ //sb.Begin();
+ //foreach (var entry in data)
+ //{
+ // int x = (int)(entry.GridBox.MinPoint.X - Main.screenPosition.X);
+ // int y = (int)(-entry.GridBox.MaxPoint.Y - Main.screenPosition.Y);
+ // int w = (int)(entry.GridBox.MaxPoint.X - entry.GridBox.MinPoint.X);
+ // int h = (int)(entry.GridBox.MaxPoint.Y - entry.GridBox.MinPoint.Y);
+ // sb.Draw(TextureAssets.MagicPixel.Value, new Rectangle(x, y, w, h), Color.White * MathHelper.Lerp(0.1f, 0.1f, entry.Layer / 32f));
+ //}
+
+ //sb.End();
+ }
+
+ public override bool TestSingleCollision(AABB aabb, Vector2 velocity, float deltaTime, List targetTags)
+ {
+ foreach (var tag in targetTags)
+ {
+ if (!_groups.ContainsKey(tag))
+ {
+ continue;
+ }
+ var bvhThisGroup = _bvhForGroup[tag];
+
+ if (bvhThisGroup.QueryRange(aabb).Count > 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs
index c18773689..bba12c11f 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/BruteForceDetect.cs
@@ -7,33 +7,27 @@
namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
{
- ///
- /// 暴力遍历AABB的粗粒度碰撞检测算法
- ///
- public class BruteForceDetect : BroadPhase
+ ///
+ /// 暴力遍历AABB的粗粒度碰撞检测算法
+ ///
+ public class BruteForceDetect : IBroadPhase
{
- private struct BruteForceEntry
- {
- public int ColliderId;
- public AABB BoundingBox;
- public bool IsDynamic;
- }
private List _colliders;
- private Dictionary> _groups;
+ private Dictionary> _groups;
public BruteForceDetect(CollisionGraph graph) : base(graph)
{
- _colliders = new List();
- _groups = new Dictionary>();
+ _colliders = new List();
+ _groups = new Dictionary>();
}
- private void GroupInnerDetection(List entries,
+ private void GroupInnerDetection(List entries,
List> collisionResults)
{
for (int i = 0; i < entries.Count; i++)
{
for (int j = i + 1; j < entries.Count; j++)
{
- if ((entries[i].IsDynamic || entries[j].IsDynamic)
+ if ((entries[i].IsDynamic || entries[j].IsDynamic)
&& entries[i].BoundingBox.Intersects(entries[j].BoundingBox))
{
collisionResults.Add(new KeyValuePair(_colliders[entries[i].ColliderId],
@@ -43,15 +37,15 @@ private void GroupInnerDetection(List entries,
}
}
- private void GroupOuterDetection(List groupA,
- List groupB,
+ private void GroupOuterDetection(List groupA,
+ List groupB,
List> collisionResults)
{
for (int i = 0; i < groupA.Count; i++)
{
for (int j = 0; j < groupB.Count; j++)
{
- if ((groupA[i].IsDynamic || groupB[j].IsDynamic)
+ if ((groupA[i].IsDynamic || groupB[j].IsDynamic)
&& groupA[i].BoundingBox.Intersects(groupB[j].BoundingBox))
{
collisionResults.Add(new KeyValuePair(_colliders[groupA[i].ColliderId],
@@ -64,14 +58,19 @@ private void GroupOuterDetection(List groupA,
public override List> GetCollisionPairs(float deltaTime)
{
List> finalPairs = new List>();
- foreach(var group in _groups)
+ foreach (var group in _groups)
{
var thisgroup = _groups[group.Key];
- GroupInnerDetection(thisgroup, finalPairs);
+
if (_collisionGraph.Graph.ContainsKey(group.Key))
{
foreach (var dual in _collisionGraph.Graph[group.Key])
{
+ if (dual == group.Key)
+ {
+ GroupInnerDetection(thisgroup, finalPairs);
+ continue;
+ }
if (!_groups.ContainsKey(dual))
continue;
GroupOuterDetection(thisgroup, _groups[dual], finalPairs);
@@ -86,11 +85,11 @@ public override void Prepare(List objects, float deltaTime)
_colliders.Clear();
_colliders.EnsureCapacity(objects.Count);
_groups.Clear();
- for(int i = 0; i < objects.Count; i++)
+ for (int i = 0; i < objects.Count; i++)
{
var obj = objects[i];
_colliders.Add(obj.Collider);
- var entry = new BruteForceEntry()
+ var entry = new ColliderEntry()
{
ColliderId = i,
BoundingBox = obj.Collider.GetAABB(deltaTime),
@@ -103,13 +102,59 @@ public override void Prepare(List objects, float deltaTime)
}
else
{
- _groups.Add(obj.Tag, new List()
+ _groups.Add(obj.Tag, new List()
{
entry
});
}
}
}
+ public override List GetSingleCollision(AABB aabb, Vector2 velocity, float deltaTime, List targetTags)
+ {
+ List colliders = new List();
+ foreach (var tag in targetTags)
+ {
+ if (!_groups.ContainsKey(tag))
+ {
+ continue;
+ }
+ var thisgroup = _groups[tag];
+
+ foreach (var entry in thisgroup)
+ {
+ if (entry.BoundingBox.Intersects(aabb))
+ {
+ colliders.Add(_colliders[entry.ColliderId]);
+ }
+ }
+ }
+ return colliders;
+ }
+ public override void DrawDebugInfo(SpriteBatch sb)
+ {
+
+ }
+
+ public override bool TestSingleCollision(AABB aabb, Vector2 velocity, float deltaTime, List targetTags)
+ {
+ foreach (var tag in targetTags)
+ {
+ if (!_groups.ContainsKey(tag))
+ {
+ continue;
+ }
+ var thisgroup = _groups[tag];
+
+ foreach (var entry in thisgroup)
+ {
+ if (entry.BoundingBox.Intersects(aabb))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
}
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs
index 5a3183227..757313d91 100644
--- a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/CollisionGraph.cs
@@ -13,7 +13,7 @@ namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
public class CollisionGraph
{
public static CollisionGraph DefualtGraph
- = new CollisionGraph(new Dictionary>() { { "Default", new List() } });
+ = new CollisionGraph(new Dictionary>() { { "Default", new List() { "Default"} } });
public Dictionary> Graph
{
get;
@@ -47,8 +47,6 @@ public void AddDoubleEdge(string groupA, string groupB)
public void AddSingleEdge(string groupA, string groupB)
{
- if (groupA == groupB)
- return;
if (Graph.ContainsKey(groupA))
{
Graph[groupA].Add(groupB);
diff --git a/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/HashGridMethod.cs b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/HashGridMethod.cs
new file mode 100644
index 000000000..d7f303e00
--- /dev/null
+++ b/Sources/Everglow.Core/Physics/PBEngine/Collision/BroadPhase/HashGridMethod.cs
@@ -0,0 +1,158 @@
+using Everglow.Commons.Physics.PBEngine.Collision.BroadPhase.Structure;
+using Everglow.Commons.Physics.PBEngine.Collision.Colliders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria;
+using Terraria.GameContent;
+
+namespace Everglow.Commons.Physics.PBEngine.Collision.BroadPhase
+{
+ internal class HashGridMethod : IBroadPhase
+ {
+ private List _colliders;
+ private Dictionary _groups;
+ private int _curHashGridSize;
+ private int _prevHashGridSize;
+ private long _prevPairTime;
+ private long _prev2PairTime;
+
+ public HashGridMethod(CollisionGraph graph) : base(graph)
+ {
+ _colliders = new List();
+ _groups = new Dictionary();
+ _prevHashGridSize = 256;
+ _curHashGridSize = 256;
+
+ _prev2PairTime = long.MaxValue;
+ _prevPairTime = long.MinValue;
+ }
+
+ public override void DrawDebugInfo(SpriteBatch sb)
+ {
+ if (!_groups.ContainsKey("Default"))
+ return;
+ //var data = _groups["Default"].GetProfilingData();
+ //sb.Begin();
+ //foreach (var entry in data)
+ //{
+ // int x = (int)(entry.GridBox.MinPoint.X - Main.screenPosition.X);
+ // int y = (int)(-entry.GridBox.MaxPoint.Y - Main.screenPosition.Y);
+ // int w = (int)(entry.GridBox.MaxPoint.X - entry.GridBox.MinPoint.X);
+ // int h = (int)(entry.GridBox.MaxPoint.Y - entry.GridBox.MinPoint.Y);
+ // sb.Draw(TextureAssets.MagicPixel.Value, new Rectangle(x, y, w, h), Color.White * MathHelper.Lerp(0.1f, 0.5f, entry.NumObjects / 64f));
+ //}
+
+ //sb.End();
+ }
+
+ public override List> GetCollisionPairs(float deltaTime)
+ {
+ Stopwatch sw = Stopwatch.StartNew();
+ List