/** Company: Shout3D LLC Project: Shout3D 2.0 Sample Code Class: Pyramid Date: August 31, 1999 Description: Pyramid geometry, subclass of IndexedFaceSet (C) Copyright Shout3D LLC. - 1997-2001 - All rights reserved */ package custom_nodes; import shout3d.core.*; /** * Pyramid. * * Subclass of IndexedFaceSet * Adds three fields -- height width and depth. * When any of these changes, the Pyramid recalculates the * vertices of its geometry. * * @author Paul Isaacs * @author Jim Stewartson * @author Dave Westwood */ public class Pyramid extends IndexedFaceSet implements FieldObserver { final public FloatField width = new FloatField(this, "width", Field.NON_NEGATIVE_FLOAT, 1); final public FloatField height = new FloatField(this, "height", Field.NON_NEGATIVE_FLOAT, 1); final public FloatField depth = new FloatField(this, "depth", Field.NON_NEGATIVE_FLOAT, 1); private float[] normalizedCoords = { -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 0, 1, 0 }; private int[] myCoordIndex = { 0, 3, 2, 1, -1, // base is a quad 0, 1, 4, -1, 1, 2, 4, -1, 2, 3, 4, -1, 3, 0, 4, -1 }; /** * Constructs a default Pyramid */ public Pyramid() { // Watch the 3 new fields to update vertices when they change width.addFieldObserver(this, null); height.addFieldObserver(this, null); depth.addFieldObserver(this, null); // Set the IFS fields to create the initial geometry. calculateVertices(); coordIndex.setValue(myCoordIndex); } /** * Clean up. Subclasses must call this from within their own finalize() method */ protected void finalize() throws Throwable { width.removeFieldObserver(this); height.removeFieldObserver(this); depth.removeFieldObserver(this); // Must call this or super classes will not properly finalize. super.finalize(); } /** * * Subclasses must call this from within their own onFieldChange() method. * */ public void onFieldChange(Field theField, Object userData) { if ( theField == width || theField == height || theField == depth) { calculateVertices(); } else { // Call the super class, it's not a field this node cares about. super.onFieldChange(theField, userData); } } float[] cVals = null; /** * Calculates the values of the vertices based on the width/height/depth * fields. */ public void calculateVertices() { // Start with the coords in the field, reallocate if there are // the wrong amount. Node testNode = coord.getValue(); Coordinate cNode = null; if (testNode != null && testNode instanceof Coordinate) cNode = (Coordinate) testNode; else { cNode = new Coordinate(); coord.setValue(cNode); } cVals = cNode.point.getValue(); if (cVals == null || cVals.length != normalizedCoords.length) cVals = new float[normalizedCoords.length]; // Scale the normalized coords by the fields to create the // node's new coordinate values. for (int i = 0; i < normalizedCoords.length-2; i += 3){ cVals[i] = width.getValue() * normalizedCoords[i]; cVals[i+1] = height.getValue() * normalizedCoords[i+1]; cVals[i+2] = depth.getValue() * normalizedCoords[i+2]; } // Set the coord field with the new values cNode.point.setValue(cVals); } }