mirror of
https://github.com/processing/processing4.git
synced 2026-06-08 16:40:46 +02:00
Added center() method, updated ParticleSystem example
This commit is contained in:
@@ -1,27 +1,98 @@
|
||||
PShape system;
|
||||
|
||||
PShape particles;
|
||||
PImage sprite;
|
||||
|
||||
int npartTotal = 1000;
|
||||
int npartPerFrame = 10;
|
||||
float speed = 1.0;
|
||||
float gravity = 0.05;
|
||||
float partSize = 20;
|
||||
|
||||
int partLifetime;
|
||||
PVector velocities[];
|
||||
int lifetimes[];
|
||||
|
||||
void setup() {
|
||||
size(500, 500, P3D);
|
||||
|
||||
system = createShape(PShape.GROUP);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PShape pt = createShape(POINT);
|
||||
pt.strokeWeight(20);
|
||||
pt.stroke(random(255), random(255), random(255));
|
||||
pt.vertex(random(width), random(height));
|
||||
system.addShape(pt);
|
||||
pt.end();
|
||||
size(640, 480, P3D);
|
||||
frameRate(120);
|
||||
|
||||
particles = createShape(PShape.GROUP);
|
||||
sprite = loadImage("sprite.png");
|
||||
|
||||
for (int n = 0; n < npartTotal; n++) {
|
||||
PShape part = createShape(QUAD);
|
||||
part.noStroke();
|
||||
part.texture(sprite);
|
||||
part.vertex(-partSize/2, -partSize/2, 0, 0);
|
||||
part.vertex(+partSize/2, -partSize/2, sprite.width, 0);
|
||||
part.vertex(+partSize/2, +partSize/2, sprite.width, sprite.height);
|
||||
part.vertex(-partSize/2, +partSize/2, 0, sprite.height);
|
||||
part.end();
|
||||
particles.addShape(part);
|
||||
}
|
||||
|
||||
partLifetime = npartTotal / npartPerFrame;
|
||||
initVelocities();
|
||||
initLifetimes();
|
||||
|
||||
// Writing to the depth buffer is disabled to avoid rendering
|
||||
// artifacts due to the fact that the particles are semi-transparent
|
||||
// but not z-sorted.
|
||||
hint(DISABLE_DEPTH_MASK);
|
||||
}
|
||||
|
||||
public void draw () {
|
||||
background(255);
|
||||
void draw () {
|
||||
background(0);
|
||||
|
||||
shape(system);
|
||||
|
||||
for (int i = 0; i < system.getChildCount(); i++) {
|
||||
PShape pt = system.getChild(i);
|
||||
pt.translate(random(-5, 5), random(-5, 5), random(-5, 5));
|
||||
for (int n = 0; n < particles.getChildCount(); n++) {
|
||||
PShape part = particles.getChild(n);
|
||||
|
||||
lifetimes[n]++;
|
||||
if (lifetimes[n] == partLifetime) {
|
||||
lifetimes[n] = 0;
|
||||
}
|
||||
|
||||
if (0 <= lifetimes[n]) {
|
||||
if (lifetimes[n] == 0) {
|
||||
// Re-spawn dead particle
|
||||
part.center(mouseX, mouseY);
|
||||
float a = random(0, TWO_PI);
|
||||
float s = random(0.5 * speed, 0.5 * speed);
|
||||
velocities[n].x = s * cos(a);
|
||||
velocities[n].y = s * sin(a);
|
||||
}
|
||||
else {
|
||||
part.translate(velocities[n].x, velocities[n].y);
|
||||
velocities[n].y += gravity;
|
||||
}
|
||||
|
||||
float a = 1.0 - float(lifetimes[n]) / partLifetime;
|
||||
part.fill(255, a * 255);
|
||||
} else {
|
||||
part.fill(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
shape(particles);
|
||||
|
||||
if (frameCount % 10 == 0) println(frameRate);
|
||||
}
|
||||
|
||||
void initVelocities() {
|
||||
velocities = new PVector[npartTotal];
|
||||
for (int n = 0; n < velocities.length; n++) {
|
||||
velocities[n] = new PVector();
|
||||
}
|
||||
}
|
||||
|
||||
void initLifetimes() {
|
||||
// Initializing particles with negative lifetimes so they are added
|
||||
// progressively into the screen during the first frames of the sketch
|
||||
lifetimes = new int[npartTotal];
|
||||
int t = -1;
|
||||
for (int n = 0; n < lifetimes.length; n++) {
|
||||
if (n % npartPerFrame == 0) {
|
||||
t++;
|
||||
}
|
||||
lifetimes[n] = -t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7534,8 +7534,208 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
return newSize;
|
||||
}
|
||||
|
||||
public void applyMatrix(PMatrix2D tr) {
|
||||
public void center(float cx, float cy) {
|
||||
int index;
|
||||
|
||||
// Computing current center
|
||||
float cx0 = 0;
|
||||
float cy0 = 0;
|
||||
for (int i = 0; i < fillVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
cx0 += fillVertices[index++];
|
||||
cy0 += fillVertices[index ];
|
||||
}
|
||||
for (int i = 0; i < lineVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
cx0 += lineVertices[index++];
|
||||
cy0 += lineVertices[index ];
|
||||
}
|
||||
for (int i = 0; i < pointVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
cx0 += pointVertices[index++];
|
||||
cy0 += pointVertices[index ];
|
||||
}
|
||||
int nt = fillVertexCount + lineVertexCount + pointVertexCount;
|
||||
if (0 < nt) {
|
||||
cx0 /= nt;
|
||||
cy0 /= nt;
|
||||
}
|
||||
|
||||
float tx = cx - cx0;
|
||||
float ty = cy - cy0;
|
||||
|
||||
if (0 < fillVertexCount) {
|
||||
for (int i = 0; i < fillVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
fillVertices[index++] += tx;
|
||||
fillVertices[index ] += ty;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < lineVertexCount) {
|
||||
for (int i = 0; i < lineVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
lineVertices[index++] += tx;
|
||||
lineVertices[index ] += ty;
|
||||
|
||||
index = 4 * i;
|
||||
lineAttributes[index++] += tx;
|
||||
lineAttributes[index ] += ty;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < pointVertexCount) {
|
||||
for (int i = 0; i < pointVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
pointVertices[index++] += tx;
|
||||
pointVertices[index ] += ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void center(float cx, float cy, float cz) {
|
||||
int index;
|
||||
|
||||
// Computing current center
|
||||
float cx0 = 0;
|
||||
float cy0 = 0;
|
||||
float cz0 = 0;
|
||||
for (int i = 0; i < fillVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
cx0 += fillVertices[index++];
|
||||
cy0 += fillVertices[index++];
|
||||
cz0 += fillVertices[index ];
|
||||
}
|
||||
for (int i = 0; i < lineVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
cx0 += lineVertices[index++];
|
||||
cy0 += lineVertices[index++];
|
||||
cz0 += lineVertices[index ];
|
||||
}
|
||||
for (int i = 0; i < pointVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
cx0 += pointVertices[index++];
|
||||
cy0 += pointVertices[index++];
|
||||
cz0 += pointVertices[index ];
|
||||
}
|
||||
int nt = fillVertexCount + lineVertexCount + pointVertexCount;
|
||||
if (0 < nt) {
|
||||
cx0 /= nt;
|
||||
cy0 /= nt;
|
||||
cz0 /= nt;
|
||||
}
|
||||
|
||||
float tx = cx - cx0;
|
||||
float ty = cy - cy0;
|
||||
float tz = cz - cz0;
|
||||
|
||||
if (0 < fillVertexCount) {
|
||||
for (int i = 0; i < fillVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
fillVertices[index++] += tx;
|
||||
fillVertices[index++] += ty;
|
||||
fillVertices[index ] += tz;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < lineVertexCount) {
|
||||
for (int i = 0; i < lineVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
lineVertices[index++] += tx;
|
||||
lineVertices[index++] += ty;
|
||||
lineVertices[index ] += tz;
|
||||
|
||||
index = 4 * i;
|
||||
lineAttributes[index++] += tx;
|
||||
lineAttributes[index++] += ty;
|
||||
lineAttributes[index ] += tz;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < pointVertexCount) {
|
||||
for (int i = 0; i < pointVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
pointVertices[index++] += tx;
|
||||
pointVertices[index++] += ty;
|
||||
pointVertices[index ] += tz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyMatrix(PMatrix2D tr) {
|
||||
if (0 < fillVertexCount) {
|
||||
int index;
|
||||
|
||||
for (int i = 0; i < fillVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
float x = fillVertices[index++];
|
||||
float y = fillVertices[index ];
|
||||
|
||||
index = 3 * i;
|
||||
float nx = fillNormals[index++];
|
||||
float ny = fillNormals[index ];
|
||||
|
||||
index = 3 * i;
|
||||
fillVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02;
|
||||
fillVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12;
|
||||
|
||||
index = 3 * i;
|
||||
fillNormals[index++] = nx * tr.m00 + ny * tr.m01;
|
||||
fillNormals[index ] = nx * tr.m10 + ny * tr.m11;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < lineVertexCount) {
|
||||
int index;
|
||||
|
||||
for (int i = 0; i < lineVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
float x = lineVertices[index++];
|
||||
float y = lineVertices[index ];
|
||||
|
||||
index = 3 * i;
|
||||
float nx = lineNormals[index++];
|
||||
float ny = lineNormals[index ];
|
||||
|
||||
index = 4 * i;
|
||||
float xa = lineAttributes[index++];
|
||||
float ya = lineAttributes[index ];
|
||||
|
||||
index = 3 * i;
|
||||
lineVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02;
|
||||
lineVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12;
|
||||
|
||||
index = 3 * i;
|
||||
lineNormals[index++] = nx * tr.m00 + ny * tr.m01;
|
||||
lineNormals[index ] = nx * tr.m10 + ny * tr.m11;
|
||||
|
||||
index = 4 * i;
|
||||
lineAttributes[index++] = xa * tr.m00 + ya * tr.m01 + tr.m02;
|
||||
lineAttributes[index ] = xa * tr.m10 + ya * tr.m11 + tr.m12;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < pointVertexCount) {
|
||||
int index;
|
||||
|
||||
for (int i = 0; i < pointVertexCount; i++) {
|
||||
index = 3 * i;
|
||||
float x = pointVertices[index++];
|
||||
float y = pointVertices[index ];
|
||||
|
||||
index = 3 * i;
|
||||
float nx = pointNormals[index++];
|
||||
float ny = pointNormals[index ];
|
||||
|
||||
index = 3 * i;
|
||||
pointVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02;
|
||||
pointVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12;
|
||||
|
||||
index = 3 * i;
|
||||
pointNormals[index++] = nx * tr.m00 + ny * tr.m01;
|
||||
pointNormals[index ] = nx * tr.m10 + ny * tr.m11;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyMatrix(PMatrix3D tr) {
|
||||
@@ -7625,8 +7825,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
pointNormals[index++] = nx * tr.m10 + ny * tr.m11 + nz * tr.m12;
|
||||
pointNormals[index ] = nx * tr.m20 + ny * tr.m21 + nz * tr.m22;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -429,6 +429,11 @@ public class PShape3D extends PShape {
|
||||
// Drawing methods
|
||||
|
||||
|
||||
public void textureMode(int mode) {
|
||||
textureMode = mode;
|
||||
}
|
||||
|
||||
|
||||
public void texture(PImage tex) {
|
||||
texture = tex;
|
||||
}
|
||||
@@ -468,6 +473,11 @@ public class PShape3D extends PShape {
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float u, float v) {
|
||||
vertex(x, y, 0, u, v);
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z) {
|
||||
vertex(x, y, z, 0, 0);
|
||||
}
|
||||
@@ -765,9 +775,85 @@ public class PShape3D extends PShape {
|
||||
|
||||
// Geometric transformations
|
||||
|
||||
public void center(float cx, float cy) {
|
||||
if (family == GROUP) {
|
||||
// for (int i = 0; i < childCount; i++) {
|
||||
// PShape3D child = (PShape3D) children[i];
|
||||
// child.center(cx, cy);
|
||||
// }
|
||||
} else {
|
||||
tess.center(cx, cy);
|
||||
|
||||
modified = true;
|
||||
if (0 < tess.fillVertexCount) {
|
||||
modifiedFillVertices = true;
|
||||
}
|
||||
if (0 < tess.lineVertexCount) {
|
||||
modifiedLineVertices = true;
|
||||
modifiedLineAttributes = true;
|
||||
}
|
||||
if (0 < tess.pointVertexCount) {
|
||||
modifiedPointVertices = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void center(float cx, float cy, float cz) {
|
||||
if (family == GROUP) {
|
||||
// for (int i = 0; i < childCount; i++) {
|
||||
// PShape3D child = (PShape3D) children[i];
|
||||
// child.center(cx, cy, cz);
|
||||
// }
|
||||
|
||||
// calculate current center of all child shapes
|
||||
// translate to the new center.
|
||||
|
||||
} else {
|
||||
tess.center(cx, cy, cz);
|
||||
|
||||
modified = true;
|
||||
if (0 < tess.fillVertexCount) {
|
||||
modifiedFillVertices = true;
|
||||
}
|
||||
if (0 < tess.lineVertexCount) {
|
||||
modifiedLineVertices = true;
|
||||
modifiedLineAttributes = true;
|
||||
}
|
||||
if (0 < tess.pointVertexCount) {
|
||||
modifiedPointVertices = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void translate(float tx, float ty) {
|
||||
// TODO: implement for geometry shapes.
|
||||
super.translate(tx, ty);
|
||||
if (family == GROUP) {
|
||||
// TODO: make sure that for group shapes, just applying the
|
||||
// gl transformation is efficient enough (might depend on
|
||||
// how much geometry is inside the group).
|
||||
super.translate(tx, ty);
|
||||
} else {
|
||||
checkMatrix(2);
|
||||
matrix.translate(tx, ty);
|
||||
tess.applyMatrix((PMatrix2D) matrix);
|
||||
|
||||
modified = true;
|
||||
if (0 < tess.fillVertexCount) {
|
||||
modifiedFillVertices = true;
|
||||
modifiedFillNormals = true;
|
||||
}
|
||||
if (0 < tess.lineVertexCount) {
|
||||
modifiedLineVertices = true;
|
||||
modifiedLineNormals = true;
|
||||
modifiedLineAttributes = true;
|
||||
}
|
||||
if (0 < tess.pointVertexCount) {
|
||||
modifiedPointVertices = true;
|
||||
modifiedPointNormals = true;
|
||||
}
|
||||
|
||||
// So the transformation is not applied again when drawing
|
||||
matrix = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void translate(float tx, float ty, float tz) {
|
||||
@@ -781,7 +867,7 @@ public class PShape3D extends PShape {
|
||||
matrix.translate(tx, ty, tz);
|
||||
tess.applyMatrix((PMatrix3D) matrix);
|
||||
|
||||
modified = true;
|
||||
modified = true;
|
||||
if (0 < tess.fillVertexCount) {
|
||||
modifiedFillVertices = true;
|
||||
modifiedFillNormals = true;
|
||||
@@ -2543,7 +2629,7 @@ public class PShape3D extends PShape {
|
||||
offset = newOffset;
|
||||
}
|
||||
|
||||
if (data.length / ncoords == size + newSize) {
|
||||
if (data.length / ncoords <= size + newSize) {
|
||||
expand(size + newSize);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user