var m = 4, n = 3;
var cp = new Float32Array([ // petal
0,.3,.2,.6, 0,.6,.3,.6, 0,.3,.2,.6, // x m*n points
0,-.3,-.3,0, 0,0,0,0, 0,.3,.4,0, // y
0,.2,.5,.6, 0,.2,.5,.6, 0,.2,.5,.6, // z
0,0,0,0, 0,0,0,0, 0,0,0,0, // red
0,0,0,0, 0,0,0,0, 0,0,0,0, // green
1,1,1,1, -.8,-.4,.8,1, 1,1,1,1]); // blue
Next Bezier basis functions and regular sm×sn
rectangular mesh are generated.
BezierFunc(m, sm, Bm); BezierFunc(n, sn, Bn); splinePatch(m, n, sm, sn2, Bm, Bn, cp, strips, saw);Note, that sn = 2 sn2 + 1 is odd. Parameter strips = {0, 1, 2, 3} corresponds to different color patterning of the patches. saw = true corresponds to sawtouth patch borders. They are produced by removing part of border triangles.
rotX( fi, mn, cp1);
rotX_p(fi, off0, off, pt){
E.g. rotX() rotates mn control points and
rotX_p() rotates meshe's points from off0
to off end so on.
See e.g. "flower" source for details.
attribute vec3 aPos;
attribute vec3 aPos2;
attribute vec3 aCol;
uniform mat4 mvMatrix;
uniform float a;
varying vec3 color;
void main(void) {
gl_Position = mvMatrix * vec4(mix(aPos, aPos2, a), 1.);
color = aCol;
}
Therefore for 0 < a < 1 you get smooth model morphing
between the two frames. For animation you need some "sorcery"
to prepare a and choose appropriate meshes from 10 key-frames
(the an_off parameter).
var ti = new Date().getTime();
if (ti - Tanim > Tmorph){ Tanim = ti;}
var a = 10*(ti - Tanim) / Tmorph;
var an_off = pi10*Math.floor(a);
a -= Math.floor(a);
gl.uniform1f( aLoc, a );
gl.drawElements(gl.TRIANGLES, pi10, gl.UNSIGNED_INT, 4*an_off);
pi10 is the "size" of one frame.
One can use similar algorithms to distribute plants on terrains. Use Van der Waals forces to simulate attraction and make groves.
For simple models I don't need any frameworks. I think,
to make something bigger you need choose one (e.g. ThreeJS,
PlayCanvas...).
Unfortunately, I failed to move some of my demos to PlayCanvas.
Don't you like to help me? :)
...