* Draw the mesh (automatically called by melonJS). Picks between two * projection paths based on the camera that was active when this mesh * was added to the world (captured in Mesh#onActivateEvent): * * - **Camera3d** → world-space output via Mesh#_projectVerticesWorld. *
(renderer, viewport)
| 825 | * @param {Camera2d} [viewport] - the camera rendering this frame |
| 826 | */ |
| 827 | draw(renderer, viewport) { |
| 828 | // Prefer the live viewport (per-draw) over the flag captured |
| 829 | // at activation. Falling back to the flag when no viewport is |
| 830 | // passed preserves test callers that call `draw(renderer)` |
| 831 | // directly. |
| 832 | const useWorldSpace = |
| 833 | viewport !== undefined |
| 834 | ? viewport instanceof Camera3d |
| 835 | : this._useWorldSpace === true; |
| 836 | if (useWorldSpace) { |
| 837 | if (this._worldSpace !== true) { |
| 838 | this._setupWorldSpace(); |
| 839 | } |
| 840 | // Camera3d path. The reflection bridge (Y-only negate) inverts |
| 841 | // winding, so it needs the reversed indices to keep |
| 842 | // `cullBackFaces: true` correct. The rotation bridge |
| 843 | // (`rightHanded`: Y+Z negate) preserves winding, so the |
| 844 | // original indices are already correct. |
| 845 | this.indices = this.rightHanded |
| 846 | ? this._indicesOriginal |
| 847 | : this._indicesReversed; |
| 848 | // Emit FINAL world coordinates: the node origin is baked into |
| 849 | // pos/depth and the geometry carries its own extent. The anchor |
| 850 | // offset is suppressed for this path via `applyAnchorTransform` |
| 851 | // (set in `preDraw`), so it does not leak into the view matrix. |
| 852 | this._projectVerticesWorld(this.pos.x, this.pos.y, this.depth); |
| 853 | // world-space normals — only when this mesh is lit (the unlit batcher |
| 854 | // never reads `normals`, so projecting them otherwise is wasted |
| 855 | // per-frame work; glTF meshes carry normals even when the scene has |
| 856 | // no lights). No-op without source normals. |
| 857 | if (this.lit === true) { |
| 858 | this._projectNormalsWorld(); |
| 859 | } |
| 860 | } else { |
| 861 | // Camera2d / no-camera path: restore the original winding. |
| 862 | // Important when the same Mesh instance was previously drawn |
| 863 | // under Camera3d (`_setupWorldSpace` ran) and is now being |
| 864 | // re-rendered under a 2D camera — without this restore the |
| 865 | // reversed indices stay in place and front-facing triangles |
| 866 | // get culled, leaving the model looking inside-out. |
| 867 | this.indices = this._indicesOriginal; |
| 868 | this._projectVertices(this.pos.x, this.pos.y, 1000); |
| 869 | } |
| 870 | renderer.drawMesh(this); |
| 871 | } |
| 872 | |
| 873 | /** |
| 874 | * Compute a 2D convex hull polygon from the current projected vertices. |
nothing calls this directly
no test coverage detected