public void setNormals() { // first get normals for all faces int numFaces = F.size(); for (Face f : F) { Edge e = E.get(f.e); Vec3 v1 = V.get(e.v).coord; e = E.get(e.next); Vec3 v2 = V.get(e.v).coord; e = E.get(e.next); Vec3 v3 = V.get(e.v).coord; // set the normal for this face Vec3 U = Vec3.sub(v2, v1); Vec3 V = Vec3.sub(v3, v1); float nx = U.y * V.z - U.z * V.y; float ny = U.z * V.x - U.x * V.z; float nz = U.x * V.y - U.y * V.x; f.norm = new Vec3(nx, ny, nz); f.norm.normalize(); } // next set normals for all vertices for (Vert v : V) { Vector<Vec3> norms = new Vector<Vec3>(); Edge e = E.get(v.e); Edge eNext = e; // E.get(E.get(e.sym).next); do { // get eNext's Face's norm and store it for combining later norms.add(F.get(eNext.f).norm); eNext = E.get(E.get(eNext.sym).next); } while (e.i != eNext.i); // combine scaled norms here and set v.norm float scale = 1.0f / norms.size(); Vec3 vNorm = new Vec3(0, 0, 0); for (int i = 0; i < norms.size(); i++) vNorm = Vec3.add(vNorm, norms.get(i)); // .scale(scale)); v.norm = vNorm; v.norm.normalize(); } }
public void update(int anim, int time) { float dt = (float) viewer.getDelta() * 0.001F; float grav = AnimatedFloat.getValue(gravity, anim, time); float deaccel = AnimatedFloat.getValue(gravity2, anim, time); if (emitterType == 1 || emitterType == 2) { float rate = AnimatedFloat.getValue(emissionRate, anim, time); float life = AnimatedFloat.getValue(lifespan, anim, time); float toSpawn = 0.0F; if (life != 0.0F) toSpawn = (dt * rate) / life + spawnRemainder; else toSpawn = spawnRemainder; if (toSpawn < 1.0F) { spawnRemainder = toSpawn; if (spawnRemainder < 0.0F) spawnRemainder = 0.0F; } else { int spawnCount = (int) toSpawn; if (spawnCount + particles.size() > 1000) spawnCount = 1000 - particles.size(); spawnRemainder = toSpawn - (float) spawnCount; float w = AnimatedFloat.getValue(areaWidth, anim, time) * 0.5F; float l = AnimatedFloat.getValue(areaLength, anim, time) * 0.5F; float speed = AnimatedFloat.getValue(emissionSpeed, anim, time); float var = AnimatedFloat.getValue(speedVariation, anim, time); float spread = AnimatedFloat.getValue(verticalRange, anim, time); float spread2 = AnimatedFloat.getValue(horizontalRange, anim, time); boolean en = true; int thisAnim = anim; if (thisAnim >= enabled.length) thisAnim = 0; if (enabled.length > 0 && enabled[thisAnim].used) en = enabled[thisAnim].getValue(time) != 0; if (en) { for (int i = 0; i < spawnCount; i++) { Particle p; if (emitterType == 1) p = PlaneEmitter.newParticle(this, anim, time, w, l, speed, var, spread, spread2); else p = SphereEmitter.newParticle(this, anim, time, w, l, speed, var, spread, spread2); particles.add(p); } } } } float speed = 1.0F; Vec3 t1 = new Vec3(); Vec3 t2 = new Vec3(); Vec3 t3 = new Vec3(); Point4f d = new Point4f(); Point4f c[] = new Point4f[3]; for (int i = 0; i < 3; i++) c[i] = new Point4f(); for (int i = 0; i < particles.size(); ) { Particle p = (Particle) particles.get(i); p.speed.add( Vec3.sub(Vec3.scale(p.down, grav * dt, t1), Vec3.scale(p.dir, deaccel * dt, t2), t3)); if (slowdown > 0.0F) speed = (float) Math.exp(-1F * slowdown * p.life); p.pos.add(Vec3.scale(p.speed, speed * dt, t1)); p.life += dt; float lifePos = p.life / p.maxLife; float s1 = size.data[0].x; float s2 = 0.0F; float s3 = 0.0F; if (size.data.length > 1) s2 = size.data[1].x; else s2 = s1; if (size.data.length > 2) s3 = size.data[2].x; else s3 = s2; p.size = lifeInterp(lifePos, 0.5F, s1 * scale.x, s2 * scale.y, s3 * scale.z); int limit = Math.min(3, color.data.length); for (int j = 0; j < limit; j++) { Point3f t = color.data[j]; c[j].set(t.x / 255F, t.y / 255F, t.z / 255F, (float) transparency.data[j] / 32767F); } if (limit < 3) { Point3f t = color.data[limit - 1]; for (int j = limit - 1; j < 3; j++) c[j].set(t.x / 255F, t.y / 255F, t.z / 255F, (float) transparency.data[j] / 32767F); } lifeInterp(lifePos, 0.5F, c[0], c[1], c[2], d); p.color.set(d); if (lifePos >= 1.0F) particles.remove(i); else i++; } }
public void draw(GL2 gl) { if (particles.size() == 0) return; switch (blendMode) { case 0: // '\0' gl.glDisable(3042); gl.glDisable(3008); break; case 1: // '\001' gl.glEnable(3042); gl.glDisable(3008); gl.glBlendFunc(768, 1); break; case 2: // '\002' gl.glEnable(3042); gl.glDisable(3008); gl.glBlendFunc(770, 1); break; case 3: // '\003' gl.glDisable(3042); gl.glEnable(3008); break; case 4: // '\004' gl.glEnable(3042); gl.glDisable(3008); gl.glBlendFunc(770, 1); break; } gl.glBindTexture(3553, model.mMaterials[texture].mTextureId); gl.glPushMatrix(); if (particleType == 0 || particleType == 2) { if ((flags & 0x1000) == 0) { Vec3 view = new Vec3(viewer.getCamera().getPosition()); view.normalize(); Vec3 right = Vec3.cross(view, new Vec3(0.0F, 0.0F, 1.0F)).normalize(); Vec3 up = Vec3.cross(right, view).normalize(); int tcStart = 0; if (flags == 0x40019) tcStart++; gl.glBegin(7); int count = particles.size(); Vec3 pos = new Vec3(); Vec3 cPos = new Vec3(); Vec3 ofs = new Vec3(); for (int i = 0; i < count; i++) { Particle p = (Particle) particles.get(i); if (p.tile < texCoords.size()) { gl.glColor4f(p.color.x, p.color.y, p.color.z, p.color.w); Point2f tc[] = (Point2f[]) texCoords.get(p.tile); Vec3.add(right, up, ofs); cPos.set(p.pos); Vec3.sub(cPos, ofs.scale(p.size), pos); gl.glTexCoord2f(tc[tcStart % 4].x, tc[tcStart % 4].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.sub(right, up, ofs); Vec3.add(cPos, ofs.scale(p.size), pos); gl.glTexCoord2f(tc[(tcStart + 1) % 4].x, tc[(tcStart + 1) % 4].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.add(right, up, ofs); Vec3.add(cPos, ofs.scale(p.size), pos); gl.glTexCoord2f(tc[(tcStart + 2) % 4].x, tc[(tcStart + 2) % 4].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.sub(right, up, ofs); Vec3.sub(cPos, ofs.scale(p.size), pos); gl.glTexCoord2f(tc[(tcStart + 3) % 4].x, tc[(tcStart + 3) % 4].y); gl.glVertex3f(pos.x, pos.y, pos.z); } } gl.glEnd(); } else { gl.glBegin(7); int count = particles.size(); Vec3 pos = new Vec3(); Vec3 ofs = new Vec3(); for (int i = 0; i < count; i++) { Particle p = (Particle) particles.get(i); if (p.tile < texCoords.size()) { gl.glColor4f(p.color.x, p.color.y, p.color.z, p.color.w); Point2f tc[] = (Point2f[]) texCoords.get(p.tile); Vec3.add(p.pos, Vec3.scale(p.corners[0], p.size, ofs), pos); gl.glTexCoord2f(tc[0].x, tc[0].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.add(p.pos, Vec3.scale(p.corners[1], p.size, ofs), pos); gl.glTexCoord2f(tc[1].x, tc[1].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.add(p.pos, Vec3.scale(p.corners[2], p.size, ofs), pos); gl.glTexCoord2f(tc[2].x, tc[2].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.add(p.pos, Vec3.scale(p.corners[3], p.size, ofs), pos); gl.glTexCoord2f(tc[3].x, tc[3].y); gl.glVertex3f(pos.x, pos.y, pos.z); } } gl.glEnd(); } } else if (particleType == 1) { gl.glBegin(7); int count = particles.size(); Vec3 pos = new Vec3(); Vec3 ofs = new Vec3(); float f = 1.0F; Vec3 bv0 = new Vec3(-f, f, 0.0F); Vec3 bv1 = new Vec3(f, f, 0.0F); for (int i = 0; i < count; i++) { Particle p = (Particle) particles.get(i); if (p.tile >= texCoords.size() - 1) break; gl.glColor4f(p.color.x, p.color.y, p.color.z, p.color.w); Point2f tc[] = (Point2f[]) texCoords.get(p.tile); Vec3.add(p.pos, Vec3.scale(bv0, p.size, ofs), pos); gl.glTexCoord2f(tc[0].x, tc[0].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.add(p.pos, Vec3.scale(bv1, p.size, ofs), pos); gl.glTexCoord2f(tc[1].x, tc[1].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.add(p.origin, Vec3.scale(bv1, p.size, ofs), pos); gl.glTexCoord2f(tc[2].x, tc[2].y); gl.glVertex3f(pos.x, pos.y, pos.z); Vec3.add(p.origin, Vec3.scale(bv0, p.size, ofs), pos); gl.glTexCoord2f(tc[3].x, tc[3].y); gl.glVertex3f(pos.x, pos.y, pos.z); } gl.glEnd(); } gl.glPopMatrix(); }