Skip to content

Commit

Permalink
feat: inspect drawing for fixtures
Browse files Browse the repository at this point in the history
  • Loading branch information
KeSuave committed Dec 15, 2024
1 parent b5db27d commit cf28b9a
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 6 deletions.
47 changes: 47 additions & 0 deletions src/examples/SphereStack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Vec2 } from "planck";
import { addScenesButtons, type KAPLANCKCtx } from "../shared";

const sphereStackScene = (k: KAPLANCKCtx) => () => {
const scene = k.add([]);

const worldContainer = scene.add([k.kpWorld(new Vec2(0, 10))]);

const COUNT = 10;

worldContainer.add([
k.kpPos(k.kpCenter().add({ x: 0, y: 10 })),
k.kpRotate(),
k.kpBody(),
k.kpEdgeShape({
v1: new Vec2(-40, 0),
v2: new Vec2(40, 0),
draw: false,
}),
k.kpFixture({ density: 0 }),
]);

for (let i = 0; i < COUNT; i++) {
const sphere = worldContainer.add([
k.kpPos(
k.kpCenter().add({
x: 0,
y: 4 - 3 * i,
}),
),
k.kpRotate(),
k.kpCircleShape({ radius: 1, draw: true }),
k.kpBody({ type: "dynamic" }),
k.kpFixture({ density: 1 }),
]);

k.wait(10, () => {
sphere.setAwake(false);
});

sphere.setLinearVelocity({ x: 0, y: 50 });
}

addScenesButtons(k, scene);
};

export default sphereStackScene;
18 changes: 17 additions & 1 deletion src/lib/components/BoxShape.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GameObj, KAPLAYCtx } from "kaplay";
import { type KPShapeComp, type KPShapeOpt } from "./Shape";
import type { KPShapeColor, KPShapeComp, KPShapeOpt } from "./Shape";

import { BoxShape, type Vec2Value } from "planck";
import { getRenderProps, m2p, p2kVec2 } from "../internals";
Expand Down Expand Up @@ -65,6 +65,22 @@ export default function boxShape(
return _shape;
},

kpDrawInspect(color: KPShapeColor) {
const width = m2p(opt.width);
const height = m2p(opt.height);
const pos = k.vec2(p2kVec2(k, this.shape.m_centroid));

k.drawRect({
width,
height,
pos,
anchor: "center",
fill: true,
color: k.rgb(color.r, color.g, color.b),
opacity: color.a,
});
},

add(this: BoxShapeCompThis) {
_shape = new BoxShape(
opt.width / 2,
Expand Down
25 changes: 24 additions & 1 deletion src/lib/components/ChainShape.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GameObj, KAPLAYCtx, Vec2 as KaVec2 } from "kaplay";
import { type KPShapeComp, type KPShapeOpt } from "./Shape";
import type { KPShapeColor, KPShapeComp, KPShapeOpt } from "./Shape";

import { ChainShape, type Vec2Value } from "planck";
import { getRenderProps, p2kVec2 } from "../internals";
Expand Down Expand Up @@ -38,6 +38,29 @@ export default function chainShape(
return _shape;
},

kpDrawInspect(color: KPShapeColor) {
const vertices = this.shape.m_vertices;

const pts: KaVec2[] = [];
for (let i = 0; i < vertices.length - 1; i++) {
pts.push(p2kVec2(k, vertices[i]));

if (i === vertices.length - 2) {
pts.push(p2kVec2(k, vertices[i + 1]));
}
}

if (opt?.loop) {
pts.push(pts[0]);
}

k.drawLines({
pts,
color: k.rgb(color.r, color.g, color.b),
opacity: color.a,
});
},

add() {
_shape = new ChainShape(opt?.vertices, opt?.loop);
},
Expand Down
23 changes: 22 additions & 1 deletion src/lib/components/CircleShape.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GameObj, KAPLAYCtx } from "kaplay";
import { type KPShapeComp, type KPShapeOpt } from "./Shape";
import type { KPShapeColor, KPShapeComp, KPShapeOpt } from "./Shape";

import { CircleShape, Vec2, type Vec2Value } from "planck";
import { getRenderProps, m2p, p2kVec2 } from "../internals";
Expand Down Expand Up @@ -39,6 +39,22 @@ export default function circleShape(
return _shape;
},

kpDrawInspect(color: KPShapeColor) {
k.drawCircle({
pos: p2kVec2(k, this.shape.getCenter()),
radius: m2p(this.shape.getRadius()),
fill: true,
color: k.rgb(color.r, color.g, color.b),
opacity: color.a,
});

k.drawLine({
p1: k.vec2(),
p2: k.vec2(m2p(this.shape.getRadius()), 0),
color: k.rgb(color.r, color.g, color.b),
});
},

add() {
_shape = new CircleShape(opt?.position ?? Vec2.zero(), opt?.radius);
},
Expand All @@ -53,6 +69,11 @@ export default function circleShape(
radius: m2p(this.shape.getRadius()),
fill: opt?.fill,
});

k.drawLine({
p1: k.vec2(),
p2: k.vec2(m2p(this.shape.getRadius()), 0),
});
},
destroy() {
_shape = null;
Expand Down
15 changes: 14 additions & 1 deletion src/lib/components/EdgeShape.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GameObj, KAPLAYCtx } from "kaplay";
import { type KPShapeComp, type KPShapeOpt } from "./Shape";
import type { KPShapeColor, KPShapeComp, KPShapeOpt } from "./Shape";

import { EdgeShape, type Vec2Value } from "planck";
import { getRenderProps, p2kVec2 } from "../internals";
Expand Down Expand Up @@ -38,6 +38,19 @@ export default function edgeShape(
return _shape;
},

kpDrawInspect(color: KPShapeColor) {
const p1 = p2kVec2(k, this.shape.m_vertex1);
const p2 = p2kVec2(k, this.shape.m_vertex2);

k.drawLine({
p1,
p2,
color: k.rgb(color.r, color.g, color.b),
opacity: color.a,
width: 1,
});
},

add() {
_shape = new EdgeShape(opt?.v1, opt?.v2);
},
Expand Down
27 changes: 26 additions & 1 deletion src/lib/components/Fixture.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Comp, GameObj } from "kaplay";
import type { Fixture, FixtureDef } from "planck";
import type { KPShapeColor, KPShapeComp } from "./Shape";

import type { KPUserData } from "../types";
import type { KPBodyComp } from "./Body";
import type { KPShapeComp } from "./Shape";

export type KPFixtureDef = Omit<FixtureDef, "shape">;

Expand Down Expand Up @@ -145,7 +145,32 @@ export default function fixture(def?: KPFixtureDef): KPFixtureComp {
});
};
},
drawInspect(this: FixtureThis) {
const body = this.fixture.getBody();

const color: KPShapeColor = {
r: 200,
g: 200,
b: 200,
a: 1,
};

if (body.isDynamic()) {
color.r = 0;
color.g = 191;
color.b = 255;
} else if (body.isKinematic()) {
color.r = 238;
color.g = 130;
color.b = 238;
}

if (!body.isAwake()) {
color.a = 0.5;
}

this.kpDrawInspect(color);
},
destroy(this: FixtureThis) {
this.fixture.getBody().destroyFixture(this.fixture);

Expand Down
13 changes: 12 additions & 1 deletion src/lib/components/PolygonShape.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { GameObj, KAPLAYCtx } from "kaplay";
import { getRenderProps, p2kVec2 } from "../internals";
import { KPShapeComp, KPShapeOpt } from "./Shape";
import type { KPShapeColor, KPShapeComp, KPShapeOpt } from "./Shape";

import type { Vec2Value } from "planck";
import { PolygonShape } from "planck";
Expand Down Expand Up @@ -39,6 +39,17 @@ export default function polygonShape(
return _shape;
},

kpDrawInspect(color: KPShapeColor) {
const pts = this.shape.m_vertices.map((v) => p2kVec2(k, v));

k.drawPolygon({
pts,
fill: true,
color: k.rgb(color.r, color.g, color.b),
opacity: color.a,
});
},

add() {
_shape = new PolygonShape(opt?.vertices);
},
Expand Down
15 changes: 15 additions & 0 deletions src/lib/components/Shape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,28 @@ import type { Comp } from "kaplay";

import { type Shape } from "planck";

export interface KPShapeColor {
r: number;
g: number;
b: number;
a: number;
}

export interface KPShapeComp extends Comp {
/**
* The Shape
*
* @type {Shape}
*/
shape: Shape;

/**
* @internal
* Draws the shape for debugging purposes.
*
* @param color - The color to use for drawing the shape.
*/
kpDrawInspect(color: KPShapeColor): void;
}

export interface KPShapeOpt {
Expand Down
13 changes: 13 additions & 0 deletions src/lib/internals.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { GameObj, KAPLAYCtx, Vec2 as KaVec2, RenderProps } from "kaplay";
import { Settings, Vec2, type Vec2Value } from "planck";
import { KPBodyComp } from "./components/Body";

export function m2p(m: number) {
return m * Settings.lengthUnitsPerMeter;
Expand Down Expand Up @@ -33,3 +34,15 @@ export function getRenderProps(obj: GameObj): RenderProps {
uniform: obj.uniform,
};
}

export function hasKPBody(obj: GameObj): GameObj<KPBodyComp> | null {
if (obj.c("kpBody")) {
return obj as unknown as GameObj<KPBodyComp>;
}

if (obj.parent && obj.parent.c("kpBody")) {
return obj.parent as unknown as GameObj<KPBodyComp>;
}

return null;
}
2 changes: 2 additions & 0 deletions src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import addPairScene from "./examples/AddPair";
import applyForceScene from "./examples/ApplyForce";
import motorJointScene from "./examples/MotorJoint";
import sampleScene from "./examples/Sample";
import sphereStackScene from "./examples/SphereStack";
import tumblerScene from "./examples/Tumbler";
import webScene from "./examples/Web";
import type { KaPlanckPluginCtx } from "./lib";
Expand All @@ -22,6 +23,7 @@ export const examples: [SceneName, ExampleCheckScene][] = [
["addPair", addPairScene],
["applyForce", applyForceScene],
["motorJoint", motorJointScene],
["sphereStack", sphereStackScene],
["tumbler", tumblerScene],
["web", webScene],
];
Expand Down

0 comments on commit cf28b9a

Please sign in to comment.