-
Notifications
You must be signed in to change notification settings - Fork 1.9k
feat: add entity render mesh helpers #8960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { Debug } from '../core/debug.js'; | ||
| import { guid } from '../core/guid.js'; | ||
| import { BoundingBox } from '../core/shape/bounding-box.js'; | ||
| import { GraphNode } from '../scene/graph-node.js'; | ||
| import { getApplication } from './globals.js'; | ||
|
|
||
|
|
@@ -28,6 +29,14 @@ import { getApplication } from './globals.js'; | |
| * @import { ScrollbarComponent } from './components/scrollbar/component.js' | ||
| * @import { SoundComponent } from './components/sound/component.js' | ||
| * @import { SpriteComponent } from './components/sprite/component.js' | ||
| * @import { MeshInstance } from '../scene/mesh-instance.js' | ||
| */ | ||
|
|
||
| /** | ||
| * @callback RenderMeshInstanceCallback | ||
| * @param {MeshInstance} meshInstance - The render mesh instance. | ||
| * @param {RenderComponent|ModelComponent} component - The component that owns the mesh instance. | ||
| * @param {Entity} entity - The entity that owns the component. | ||
| */ | ||
|
|
||
| /** | ||
|
|
@@ -466,6 +475,63 @@ class Entity extends GraphNode { | |
| return this.find(entity => entity.c?.[type]).map(entity => entity.c[type]); | ||
| } | ||
|
|
||
| /** | ||
| * Executes a provided function once for each {@link MeshInstance} on this entity and all of | ||
| * its descendants. | ||
| * | ||
| * @param {RenderMeshInstanceCallback} callback - The function to execute on each mesh | ||
| * instance. | ||
| * @param {object} [thisArg] - Optional value to use as this when executing callback function. | ||
| * @example | ||
| * entity.forEachRenderMeshInstance((meshInstance) => { | ||
| * meshInstance.visible = false; | ||
| * }); | ||
| */ | ||
| forEachRenderMeshInstance(callback, thisArg) { | ||
| this.forEach((entity) => { | ||
| const render = entity.c.render; | ||
| const renderMeshes = render?.meshInstances; | ||
| for (let i = 0, len = renderMeshes?.length ?? 0; i < len; i++) { | ||
| callback.call(thisArg, renderMeshes[i], render, entity); | ||
| } | ||
|
|
||
| const model = entity.c.model; | ||
| const modelMeshes = model?.meshInstances; | ||
| for (let i = 0, len = modelMeshes?.length ?? 0; i < len; i++) { | ||
| callback.call(thisArg, modelMeshes[i], model, entity); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Gets the axis-aligned bounding box enclosing all render mesh instances on this entity and all | ||
| * of its descendants. | ||
| * | ||
| * @param {BoundingBox} [result] - The bounding box to receive the result. | ||
| * @returns {BoundingBox|null} The bounding box, or null if no render mesh instances were found. | ||
| * @example | ||
| * const aabb = entity.getAabb(); | ||
| * if (aabb) { | ||
| * // use aabb | ||
| * } | ||
| */ | ||
| getAabb(result) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure this function is good as is, I think meshInstance.aabb is only updated during rendering, so on the first frame it's not valid. we should not expose this for now till that is sorted. separate PR.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still working on this - this is not merge ready at all |
||
| let aabb = result; | ||
| let found = false; | ||
|
|
||
| this.forEachRenderMeshInstance((meshInstance) => { | ||
| if (found) { | ||
| aabb.add(meshInstance.aabb); | ||
| } else { | ||
| aabb = aabb || new BoundingBox(); | ||
| aabb.copy(meshInstance.aabb); | ||
| found = true; | ||
| } | ||
| }); | ||
|
|
||
| return found ? aabb : null; | ||
| } | ||
|
|
||
| /** | ||
| * Search the entity and all of its descendants for the first script instance of specified type. | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it called
forEachRenderMeshInstancewhen it works on model components.it should be
forEachMeshInstanceThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a draft for now - the exact names we can modify. I am just collating findings from my experiments with agents