package models import ( "fmt" "github.com/ByteArena/box2d" "math" ) // Use type `float64` for json unmarshalling of numbers. type Direction struct { Dx int32 `json:"dx,omitempty"` Dy int32 `json:"dy,omitempty"` } type Vec2D struct { X float64 `json:"x,omitempty"` Y float64 `json:"y,omitempty"` } func CreateVec2DFromB2Vec2(b2V2 box2d.B2Vec2) *Vec2D { return &Vec2D{ X: b2V2.X, Y: b2V2.Y, } } func (v2 *Vec2D) ToB2Vec2() box2d.B2Vec2 { return box2d.MakeB2Vec2(v2.X, v2.Y) } type Polygon2D struct { Anchor *Vec2D `json:"-"` // This "Polygon2D.Anchor" is used to be assigned to "B2BodyDef.Position", which in turn is used as the position of the FIRST POINT of the polygon. Points []*Vec2D `json:"-"` /* When used to represent a "polyline directly drawn in a `Tmx file`", we can initialize both "Anchor" and "Points" simultaneously. Yet when used to represent a "polyline drawn in a `Tsx file`", we have to first initialize "Points w.r.t. center of the tile-rectangle", and then "Anchor(initially nil) of the tile positioned in the `Tmx file`". Refer to https://shimo.im/docs/SmLJJhXm2C8XMzZT for more information. */ /* [WARNING] Used to cache "`TileWidth & TileHeight` of a Tsx file" only. */ TileWidth int TileHeight int /* [WARNING] Used to cache "`Width & TileHeight` of an object in Tmx file" only. */ TmxObjectWidth float64 TmxObjectHeight float64 } func MoveDynamicBody(body *box2d.B2Body, pToTargetPos *box2d.B2Vec2, inSeconds float64) { if body.GetType() != box2d.B2BodyType.B2_dynamicBody { return } body.SetTransform(*pToTargetPos, 0.0) body.SetLinearVelocity(box2d.MakeB2Vec2(0.0, 0.0)) body.SetAngularVelocity(0.0) } func PrettyPrintFixture(fix *box2d.B2Fixture) { fmt.Printf("\t\tfriction:\t%v\n", fix.M_friction) fmt.Printf("\t\trestitution:\t%v\n", fix.M_restitution) fmt.Printf("\t\tdensity:\t%v\n", fix.M_density) fmt.Printf("\t\tisSensor:\t%v\n", fix.M_isSensor) fmt.Printf("\t\tfilter.categoryBits:\t%d\n", fix.M_filter.CategoryBits) fmt.Printf("\t\tfilter.maskBits:\t%d\n", fix.M_filter.MaskBits) fmt.Printf("\t\tfilter.groupIndex:\t%d\n", fix.M_filter.GroupIndex) switch fix.M_shape.GetType() { case box2d.B2Shape_Type.E_circle: { s := fix.M_shape.(*box2d.B2CircleShape) fmt.Printf("\t\tb2CircleShape shape: {\n") fmt.Printf("\t\t\tradius:\t%v\n", s.M_radius) fmt.Printf("\t\t\toffset:\t%v\n", s.M_p) fmt.Printf("\t\t}\n") } break case box2d.B2Shape_Type.E_polygon: { s := fix.M_shape.(*box2d.B2PolygonShape) fmt.Printf("\t\tb2PolygonShape shape: {\n") for i := 0; i < s.M_count; i++ { fmt.Printf("\t\t\t%v\n", s.M_vertices[i]) } fmt.Printf("\t\t}\n") } break default: break } } func PrettyPrintBody(body *box2d.B2Body) { bodyIndex := body.M_islandIndex fmt.Printf("{\n") fmt.Printf("\tHeapRAM addr:\t%p\n", body) fmt.Printf("\ttype:\t%d\n", body.M_type) fmt.Printf("\tposition:\t%v\n", body.GetPosition()) fmt.Printf("\tangle:\t%v\n", body.M_sweep.A) fmt.Printf("\tlinearVelocity:\t%v\n", body.GetLinearVelocity()) fmt.Printf("\tangularVelocity:\t%v\n", body.GetAngularVelocity()) fmt.Printf("\tlinearDamping:\t%v\n", body.M_linearDamping) fmt.Printf("\tangularDamping:\t%v\n", body.M_angularDamping) fmt.Printf("\tallowSleep:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_autoSleepFlag) fmt.Printf("\tawake:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_awakeFlag) fmt.Printf("\tfixedRotation:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_fixedRotationFlag) fmt.Printf("\tbullet:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_bulletFlag) fmt.Printf("\tactive:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_activeFlag) fmt.Printf("\tgravityScale:\t%v\n", body.M_gravityScale) fmt.Printf("\tislandIndex:\t%v\n", bodyIndex) fmt.Printf("\tfixtures: {\n") for f := body.M_fixtureList; f != nil; f = f.M_next { PrettyPrintFixture(f) } fmt.Printf("\t}\n") fmt.Printf("}\n") } func Distance(pt1 *Vec2D, pt2 *Vec2D) float64 { dx := pt1.X - pt2.X dy := pt1.Y - pt2.Y return math.Sqrt(dx*dx + dy*dy) }