-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
The ability to construct custom p5.Geometry
using existing modeling commands.
#5393
Comments
After some reverse engineering on the codebase, I found a way to use the pre-existing API ( It's a dirty hack, probably bogus as well, but I'm pasting it here if someone might find it useful in the meanwhile for simple cases. Feel free to patch it further (I only tested it with import p5 from "p5";
// save shape as Geometry from immediate mode
p5.RendererGL.prototype.saveShape = function() {
this._processVertices(...arguments);
this.isBezier = false;
this.isQuadratic = false;
this.isCurve = false;
this.immediateMode._bezierVertex.length = 0;
this.immediateMode._quadraticVertex.length = 0;
this.immediateMode._curveVertex.length = 0;
// patch and return geometry
let g = this.immediateMode.geometry;
this._savedShapesCount = this._savedShapesCount+1 || 0;
g.gid = "saved|" + this._savedShapesCount; // assign gid to cache buffer
g._makeTriangleEdges = function() { return this; }; // shadow this function to avoid loosing edges when `model(...)` is called
// assign a new geometry to immediateMode to avoid pointer aliasing
this.immediateMode.geometry = new p5.Geometry();
return g;
};
p5.prototype.saveShape = function() {
if (this._renderer.isP3D) {
return this._renderer.saveShape(...arguments);
} else {
console.warn("Don't use saveShape in 2D mode.");
}
}; |
Wow! Thanks for the proposal. It is cool to see what people are interested in doing with p5's WebGL mode. The mission with any additions to the library is to increase access. This is broadly defined but this is also a pretty advanced use-case, it is hard for me to say that it could fall under that umbrella. That said, I agree that it is unfortunate that there are so many things that p5 does with retained geometry that are currently unavailable to people using the library. I like @sflanker 's proposal (also that's a fun hack @mttbernardini !) but I think that the complexity would need to be reduced even further to begin making an argument for accessibility. What if |
For me personally the use case is to generate a tree procedurally using an L-system (see https://alphaxmas.bubblefish.studio). My first attempt was to simply map each character of the sentence to a turtle movement using normal p5 primitives (i.e. Then I discovered the That's why I needed to figure out a way to "save" the prepared geometry rather than recreating it every draw cycle (see https://github.com/bubblefishstudio/alphaXmas/blob/main/frontend/src/p5/model.js#L72). I think I wouldn't be the only one needing to do procedural model generation, but I agree that there should be a simple and consistent API for this case (which I think it might seem advanced but in reality it's a needed step for appropriate performance scaling, immediate mode can't help more than drafting ideas) |
Great proposal! I hope this can be implemented. I'm looking forward to it. |
Take a look at this thread, there should be a few examples in there showing how to make custom geometry. |
Adding on to the existing discussion, a few more ideas: There are kind of already docs for
I'd be willing to write up the above in the doc comments if we want to commit to p5.Geometry being a public thing that people should know how to use. That said:
I'd also argue that the use case for this isn't as advanced as we think. Fractals produce a lot of detail that can be slow to render every frame, but a lot of teaching materials use p5 to teach fractals (e.g. this Nature of Code chapter) and the hardware students learn on is generally not the fastest (e.g. Chromebooks) so people might run into this limitation pretty often. I think making it easier to create I think a common question when teaching p5 and CS at the same time is how to reuse shapes. The typical answer to that is to make a function. So before people discover they need I'm thinking, if people already had a function like this: function drawIcosahedron() {
beginShape(TRIANGLES);
for (let i = 0; i < 5; i++) {
// etc
}
endShape();
} We could make a helper function that you can wrap around your function to convert the 3D shape it produces into a const icosahedron = createGeometry(function() {
beginShape(TRIANGLES);
for (let i = 0; i < 5; i++) {
// etc
}
endShape();
})
function draw() {
model(icosahedron)
} Internally it can This isn't perfect because people might expect it to run their callback every time you use the resulting model when it would actually just run it once upfront. But let me know if you feel like this sort of thing is getting closer to something we might expect beginners to be able to make use of. |
I've made a little library that works like the above, in case anyone's interested! https://github.com/davepagurek/p5.buildGeometry I'm going to try using it for a little while to see if there are limitations to this style of geometry construction. It can always continue to exist just as a library if it doesn't feel right enough to eventually be a core feature. In the mean time, let me know if you try it and have any feedback! |
How would this new feature help [increase access]
Currently creation of custom 3d objects either has poor performance (drawing multiple primitives, or using beginShape/endShape), or requires separate work in a 3d modeling tool such as Blender. For users who are new to 3d graphics and would like to create complex models procedurally without having to use a separate piece of software it would be beneficial to be able to create
p5.Geometry
objects for complex shapes purely within p5.js and get the same performance that they would with a model created in Blender and imported withloadModel
.Inspiration for this feature request: https://stackoverflow.com/questions/68898347/p5-js-3d-dot-diagram-rendering-extremely-slow
Most appropriate sub-area of p5.js?
New feature details:
Consider the following code that draws an icosahedron:
This code would get more complicated if we also wanted to specify vertex normals, and if we wanted to draw many of these it would be detrimental for performance. Converting this to
p5.Geometry
is possible but neither well documented nor trivial:What I propose is something like this:
Functions that should be available on
p5.Geometry
created in this way (could actually be a different type, likep5.MutableGeometry
):Each call that creates new faces should cause the geometry id to be regenerated so that the next time it is drawn using
model()
the WebGL buffers are recreated and cached using the new id.The text was updated successfully, but these errors were encountered: