Refactor effiecient - #3
Conversation
…er with slope navigation
…onents for Guava, Jujube, Lemon, Mango, and Papaya species. -- perfectly fined tuned version
There was a problem hiding this comment.
🟡 Not ready to approve
Several instancing refactors appear to introduce rendering/shape regressions (missing vertexColors for per-instance colors, roots scaled incorrectly, and branches losing taper), plus a potential physics regression from removing vehicle CCD at higher speeds.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR focuses on improving real-time scene performance and feel by reducing draw calls (tree instancing), lowering physics complexity (terrain collider simplification), and tuning vehicle + time-of-day update behavior.
Changes:
- Refactors multiple tree renderers to use instancing for leaves/fruits/branches/roots to reduce mesh count.
- Splits terrain into high-poly visual geometry and low-poly physics trimesh to reduce physics workload.
- Tunes vehicle motion/steering parameters and reduces time-of-day update frequency / unnecessary re-renders.
File summaries
| File | Description |
|---|---|
| src/components/scene/Vehicle.tsx | Adjusts driving constants and steering behavior; tweaks rigid body damping and collision settings. |
| src/components/scene/Terrain.tsx | Separates visual terrain mesh from a lower-resolution physics trimesh for performance. |
| src/components/scene/PapayaTree.tsx | Converts papaya leaves/fruits/scars to instanced rendering for fewer draw calls. |
| src/components/scene/OrchadCanvas.tsx | Updates time-of-day syncing logic to reduce unnecessary interval updates in auto mode. |
| src/components/scene/MangoTree.tsx | Refactors mango tree leaves/branches/flowers/fruits/roots toward instancing. |
| src/components/scene/LemonTree.tsx | Refactors lemon tree leaves/branches/flowers/roots toward instancing; adjusts fruit generation/rendering. |
| src/components/scene/JujubeTree.tsx | Refactors jujube tree leaves/branches/thorns/fruits/roots toward instancing. |
| src/components/scene/GuavaTree.tsx | Refactors guava tree leaves/branches/fruits/roots toward instancing. |
| src/components/hud/HUD.tsx | Prevents unnecessary HUD re-renders by only updating time config when values change. |
Review details
Suppressed comments (7)
src/components/scene/MangoTree.tsx:146
- Instances are assigned per-instance colors (
<Instance ... color={...} />), but the material doesn’t enablevertexColors, so instance colors may be ignored and everything may render with the material’s default color. EnablevertexColorson the material used by this<Instances>block.
<Instances range={spheres.length} limit={spheres.length}>
<sphereGeometry args={[1, 4, 4]} />
<meshStandardMaterial roughness={0.6} />
{spheres.map((s, i) => (
<Instance key={i} position={s.pos} scale={s.scale} color={s.color} />
src/components/scene/MangoTree.tsx:207
- Instances are assigned per-instance colors (
<Instance ... color={...} />), but the material doesn’t enablevertexColors, so instance colors may be ignored. EnablevertexColorson the material used by this<Instances>block.
<Instances range={fruits.length} limit={fruits.length}>
<sphereGeometry args={[1, 12, 10]} />
<meshStandardMaterial roughness={0.4} metalness={0.01} />
{fruits.map((f, i) => (
<Instance key={i} position={f.pos} scale={[f.scale * 0.85, f.scale, f.scale * 0.85]} color={f.color} />
src/components/scene/LemonTree.tsx:234
- Root instances are currently scaled non-uniformly in X vs Z (
[thickness * 0.3, ..., thickness]), which changes the previous symmetric tapered roots and likely produces unintended flattened cylinders. Use a tapered base geometry and scale X/Z uniformly bythicknessto match the prior shape.
const t = computeCylinderTransform(start, end);
arr.push({
pos: t.position,
rot: t.quaternion,
scale: [thickness * 0.3, t.length, thickness] as [number, number, number]
});
src/components/scene/JujubeTree.tsx:225
- Root instances are currently scaled non-uniformly in X vs Z (
[thickness * 0.3, ..., thickness]), which changes the prior symmetric tapered roots and likely produces unintended flattened cylinders. Use a tapered base geometry and scale X/Z uniformly bythickness.
const t = computeCylinderTransform(start, end);
arr.push({
pos: t.position,
rot: t.quaternion,
scale: [thickness * 0.3, t.length, thickness] as [number, number, number]
});
src/components/scene/JujubeTree.tsx:186
- Instances are assigned per-instance colors (
<Instance ... color={...} />), but the material doesn’t enablevertexColors, so instance colors may be ignored. EnablevertexColorson the material used by this<Instances>block.
<Instances range={fruits.length} limit={fruits.length}>
<sphereGeometry args={[1, 8, 6]} />
<meshStandardMaterial roughness={0.35} metalness={0.02} />
{fruits.map((f, i) => (
<Instance key={i} position={f.pos} scale={f.scale} color={f.color} />
))}
src/components/scene/GuavaTree.tsx:200
- Root instances are currently scaled non-uniformly in X vs Z (
[thickness * 0.3, ..., thickness]), which makes the cylinders elliptical and also removes the previous taper. Use a tapered base geometry and uniform X/Z scaling bythickness.
const t = computeCylinderTransform(start, end);
arr.push({
pos: t.position,
rot: t.quaternion,
scale: [thickness * 0.3, t.length, thickness] as [number, number, number]
});
src/components/scene/GuavaTree.tsx:151
- Instances are assigned per-instance colors (
<Instance ... color={...} />), but the material doesn’t enablevertexColors, so instance colors may be ignored. EnablevertexColorson the material used by this<Instances>block.
{fruits.length > 0 && (
<Instances range={fruits.length} limit={fruits.length}>
<sphereGeometry args={[1, 10, 8]} />
<meshStandardMaterial roughness={0.5} metalness={0.01} />
{fruits.map((f, i) => (
<Instance key={i} position={f.pos} scale={[f.scale, f.scale * 1.05, f.scale]} color={f.color} />
))}
- Files reviewed: 9/9 changed files
- Comments generated: 8
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| const REVERSE_ACCEL = 18; // reverse acceleration speed per second | ||
| const DECEL = 15; // passive coasting decay per second | ||
| const MAX_SPEED = 15; // max forward m/s | ||
| const MAX_SPEED = 20 ; // max forward m/s |
| linearDamping={0.5} | ||
| angularDamping={0} | ||
| angularDamping={0.5} | ||
| mass={80} | ||
| colliders={false} | ||
| ccd // continuous collision detection — prevents tunneling | ||
| > |
| arr.push({ | ||
| pos: t.position, | ||
| rot: t.quaternion, | ||
| scale: [thickness * 0.3, t.length, thickness] as [number, number, number] | ||
| }); |
| return branches.map((b) => { | ||
| const t = computeCylinderTransform(b.start, b.end); | ||
| const avgRadius = (b.radiusStart + b.radiusEnd) / 2; | ||
| return { | ||
| pos: t.position, |
| const t = computeCylinderTransform(b.start, b.end); | ||
| const avgRadius = (b.radiusStart + b.radiusEnd) / 2; | ||
| return { | ||
| pos: t.position, | ||
| rot: t.quaternion, | ||
| scale: [avgRadius, t.length, avgRadius] as [number, number, number], |
| const t = computeCylinderTransform(b.start, b.end); | ||
| const avgRadius = (b.radiusStart + b.radiusEnd) / 2; | ||
| return { | ||
| pos: t.position, | ||
| rot: t.quaternion, | ||
| scale: [avgRadius, t.length, avgRadius] as [number, number, number], |
| const t = computeCylinderTransform(b.start, b.end); | ||
| const avgRadius = (b.radiusStart + b.radiusEnd) / 2; | ||
| return { | ||
| pos: t.position, | ||
| rot: t.quaternion, | ||
| scale: [avgRadius, t.length, avgRadius] as [number, number, number], |
| <Instances range={fruits.length} limit={fruits.length}> | ||
| <sphereGeometry args={[1, 10, 8]} /> | ||
| <meshStandardMaterial roughness={0.4} metalness={0.01} /> | ||
| {fruits.map((f, i) => ( | ||
| <Instance key={i} position={f.pos} rotation={f.rot} scale={f.scale} color={f.color} /> | ||
| ))} |
No description provided.