115 lines
8.4 KiB
Go
115 lines
8.4 KiB
Go
package physics
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"aego/engine/module"
|
|
"aego/modules/physics/components"
|
|
"aego/modules/physics/settings"
|
|
"aego/modules/physics/stdlib"
|
|
"aego/schema"
|
|
)
|
|
|
|
func registerTypes(r *module.Registry) error {
|
|
if err := module.Enum[components.BodyType](r, "physics.BodyType",
|
|
schema.EnumValue{Name: "static", Value: int64(components.Static)},
|
|
schema.EnumValue{Name: "kinematic", Value: int64(components.Kinematic)},
|
|
schema.EnumValue{Name: "dynamic", Value: int64(components.Dynamic)},
|
|
); err != nil {
|
|
return err
|
|
}
|
|
if err := module.Enum[components.MassMode](r, "physics.MassMode",
|
|
schema.EnumValue{Name: "auto", Value: int64(components.MassAuto)},
|
|
schema.EnumValue{Name: "override", Value: int64(components.MassOverride)},
|
|
); err != nil {
|
|
return err
|
|
}
|
|
space := schema.Space(schema.Space2D)
|
|
shape := func(opts ...schema.Option) []schema.Option {
|
|
return append([]schema.Option{space,
|
|
schema.FieldDoc("offset", "Position of the shape in node space."),
|
|
schema.FieldDoc("isTrigger", "Detects overlaps and sends trigger events without pushing bodies apart."),
|
|
schema.FieldDoc("friction", "Resistance to sliding along other shapes; 0 is ice. Two shapes use the square root of the product."),
|
|
schema.FieldDoc("restitution", "Bounciness: 0 stops on impact, 1 bounces back at the same speed. Two shapes use the larger value."),
|
|
schema.FieldDoc("density", "Mass per square unit; gives the body its mass when Mass Mode is auto."),
|
|
}, opts...)
|
|
}
|
|
body := module.Component[components.Body2D](r, schema.Name(components.NameBody), space,
|
|
schema.Doc("Simulates the node as a rigid body. Colliders on the node and its children form its shape."),
|
|
schema.FieldDoc("type", "static never moves, kinematic moves by velocity, dynamic reacts to forces and contacts."),
|
|
schema.FieldDoc("massMode", "auto takes the mass from collider density, override uses Mass."),
|
|
schema.FieldDoc("gravityScale", "Multiplier of the project gravity for this body."),
|
|
schema.FieldDoc("interpolate", "Draws the body between physics steps for smooth motion; scripts still see the exact pose."),
|
|
schema.FieldDoc("layer", "Collision layer, see Project Settings → Physics."),
|
|
schema.FieldDoc("mask", "Layers this body collides with."),
|
|
schema.FieldDoc("mass", "Mass in kilograms when Mass Mode is override."),
|
|
schema.FieldDoc("linearDamping", "Slows the movement every step, like air resistance; 0 keeps the speed."),
|
|
schema.FieldDoc("angularDamping", "Slows the rotation every step; 0 keeps spinning."),
|
|
schema.FieldDoc("fixedRotation", "Keeps the body upright: contacts and torque never rotate it."),
|
|
schema.FieldDoc("bullet", "Continuous collision against other dynamic bodies, so a fast body cannot pass through them. Costs more."),
|
|
schema.FieldDoc("allowSleep", "Lets the body sleep after it comes to rest, which saves time; contacts and scripts wake it."),
|
|
schema.FieldDoc("velocity", "Current velocity in units per second, during Play."),
|
|
schema.FieldDoc("angularVelocity", "Current rotation speed in radians per second, during Play."),
|
|
schema.FieldDoc("awake", "Whether the body is simulated this step or sleeping, during Play."),
|
|
schema.ChoicesFrom("layer", settings.ID, settings.LayersList),
|
|
schema.Bitset("mask", settings.ID, settings.LayersList),
|
|
schema.Runtime("velocity", "angularVelocity", "awake"),
|
|
).Category(Menu).Display("Rigid Body 2D").Icon("comp.rigidbody").NodeIcon(80).Default(components.DefaultBody2D)
|
|
stdlib.BodyMethods(body)
|
|
return errors.Join(
|
|
body.Err(),
|
|
module.Component[components.BoxCollider2D](r, shape(schema.Name(components.NameBox),
|
|
schema.Doc("Box shape in node space."),
|
|
schema.FieldDoc("size", "Width and height in units, before the node scale."))...).
|
|
Category(Menu).Display("Box Collider 2D").Icon("comp.box").NodeIcon(70).Default(components.DefaultBox).OnAdd(fitBox).
|
|
Validate(validator[components.BoxCollider2D](components.KindBox)).Err(),
|
|
module.Component[components.CircleCollider2D](r, shape(schema.Name(components.NameCircle),
|
|
schema.Doc("Circle shape. Needs a uniform node scale."),
|
|
schema.FieldDoc("radius", "Radius in units, before the node scale."))...).
|
|
Category(Menu).Display("Circle Collider 2D").Icon("comp.circle").NodeIcon(70).Default(components.DefaultCircle).OnAdd(fitCircle).
|
|
Validate(validator[components.CircleCollider2D](components.KindCircle)).Err(),
|
|
module.Component[components.CapsuleCollider2D](r, shape(schema.Name(components.NameCapsule),
|
|
schema.Doc("Capsule along the local X axis; Length is the full extent including the caps."),
|
|
schema.FieldDoc("length", "Full length along the local X axis, caps included."),
|
|
schema.FieldDoc("radius", "Radius of the caps and half the thickness."))...).
|
|
Category(Menu).Display("Capsule Collider 2D").Icon("comp.capsule").NodeIcon(70).Default(components.DefaultCapsule).OnAdd(fitCapsule).
|
|
Validate(validator[components.CapsuleCollider2D](components.KindCapsule)).Err(),
|
|
module.Component[components.PolygonCollider2D](r, shape(schema.Name(components.NamePolygon),
|
|
schema.Doc("Convex polygon of 3 to 8 points."),
|
|
schema.FieldDoc("points", "Corners in node space, 3 to 8, forming a convex shape; edit them in the Scene View."))...).
|
|
Category(Menu).Display("Polygon Collider 2D").Icon("comp.polygon").NodeIcon(70).Default(components.DefaultPolygon).
|
|
Validate(validator[components.PolygonCollider2D](components.KindPolygon)).Err(),
|
|
module.Component[components.EdgeCollider2D](r, shape(schema.Name(components.NameEdge),
|
|
schema.Doc("Polyline for level geometry. OneSided lets bodies pass from below."),
|
|
schema.FieldDoc("points", "Points of the line in node space, at least 2; edit them in the Scene View."),
|
|
schema.FieldDoc("loop", "Joins the last point to the first, for closed outlines; needs at least 3 points."),
|
|
schema.FieldDoc("oneSided", "Collides only from above, so bodies can jump through from below, as on a platform."))...).
|
|
Category(Menu).Display("Edge Collider 2D").Icon("comp.edge").NodeIcon(70).Default(components.DefaultEdge).
|
|
Validate(validator[components.EdgeCollider2D](components.KindEdge)).Err(),
|
|
module.Component[components.DistanceJoint2D](r, schema.Name(components.NameDistance), space,
|
|
schema.Doc("Keeps a distance between this body and the Target body. Length 0 uses the distance at start."),
|
|
schema.FieldDoc("target", "The other body; both nodes need a Rigid Body 2D."),
|
|
schema.FieldDoc("anchorA", "Attachment point on this node, in node space."),
|
|
schema.FieldDoc("anchorB", "Attachment point on the Target node, in its node space."),
|
|
schema.FieldDoc("length", "Rest length in units; 0 takes the distance between the anchors at start."),
|
|
schema.FieldDoc("minLength", "Shortest allowed length. With Min and Max both 0 the joint is a rigid rod, or a spring without a lower limit when Stiffness is set."),
|
|
schema.FieldDoc("maxLength", "Longest allowed length; a rope has Min 0 and Max at the rope length."),
|
|
schema.FieldDoc("stiffness", "Spring stiffness in newtons per unit; 0 makes the length rigid within Min and Max."),
|
|
schema.FieldDoc("damping", "Spring damping; higher values stop the oscillation sooner."),
|
|
schema.FieldDoc("collideConnected", "Lets the two connected bodies collide with each other.")).
|
|
Category(Menu).Display("Distance Joint 2D").Icon("comp.joint_distance").Default(components.DefaultDistance).Err(),
|
|
module.Component[components.RevoluteJoint2D](r, schema.Name(components.NameRevolute), space,
|
|
schema.Doc("Pins this body to the Target body at Anchor, with an optional limit and motor."),
|
|
schema.FieldDoc("target", "The body this one turns around; both nodes need a Rigid Body 2D."),
|
|
schema.FieldDoc("anchor", "Pivot point in this node's space; both bodies turn around it."),
|
|
schema.FieldDoc("enableLimit", "Keeps the angle between Lower and Upper."),
|
|
schema.FieldDoc("lower", "Smallest angle in radians, relative to the angle at start."),
|
|
schema.FieldDoc("upper", "Largest angle in radians, relative to the angle at start."),
|
|
schema.FieldDoc("enableMotor", "Drives the joint at Speed, up to Max Torque."),
|
|
schema.FieldDoc("speed", "Motor speed in radians per second; negative turns the other way."),
|
|
schema.FieldDoc("maxTorque", "Strongest torque the motor may apply; with 0 the motor does nothing."),
|
|
schema.FieldDoc("collideConnected", "Lets the two connected bodies collide with each other.")).
|
|
Category(Menu).Display("Revolute Joint 2D").Icon("comp.joint_revolute").Default(components.DefaultRevolute).Err(),
|
|
)
|
|
}
|