From a323a7e7ec2299f4aad3fa7fb6abd543cc01506b Mon Sep 17 00:00:00 2001 From: codeanticode Date: Mon, 9 Jan 2012 05:20:28 +0000 Subject: [PATCH] Added center() method, updated ParticleSystem example --- core/src/processing/core/PShape.java | 10 + .../ParticleSystem/ParticleSystem.pde | 111 ++++++++-- .../processing/opengl/PGraphicsOpenGL.java | 205 +++++++++++++++++- .../src/processing/opengl/PShape3D.java | 94 +++++++- 4 files changed, 393 insertions(+), 27 deletions(-) diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index 927f8f512..72c1d0744 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -416,6 +416,8 @@ public class PShape implements PConstants { public void vertex(float x, float y) { } + public void vertex(float x, float y, float u, float v) { + } public void vertex(float x, float y, float z) { } @@ -1211,6 +1213,14 @@ public class PShape implements PConstants { // these each call matrix.translate, etc // if matrix is null when one is called, // it is created and set to identity + + public void center(float cx, float cy) { + + } + + public void center(float cx, float cy, float cz) { + + } /** * ( begin auto-generated from PShape_translate.xml ) diff --git a/java/libraries/opengl/examples/Animation/ParticleSystem/ParticleSystem.pde b/java/libraries/opengl/examples/Animation/ParticleSystem/ParticleSystem.pde index 32840ee2d..9f39932fd 100644 --- a/java/libraries/opengl/examples/Animation/ParticleSystem/ParticleSystem.pde +++ b/java/libraries/opengl/examples/Animation/ParticleSystem/ParticleSystem.pde @@ -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; + } +} diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index 5ac40ed9f..cefc4f468 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -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; } - } - + } } } diff --git a/java/libraries/opengl/src/processing/opengl/PShape3D.java b/java/libraries/opengl/src/processing/opengl/PShape3D.java index 517db0f97..991e85f4d 100644 --- a/java/libraries/opengl/src/processing/opengl/PShape3D.java +++ b/java/libraries/opengl/src/processing/opengl/PShape3D.java @@ -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); }