/** * Copyright (c) 2003-2009, Xith3D Project Group all rights reserved. * * Portions based on the Java3D interface, Copyright by Sun Microsystems. * Many thanks to the developers of Java3D and Sun Microsystems for their * innovation and design. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the 'Xith3D Project Group' nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE */ package org.xith3d.scenegraph.primitives; import org.openmali.spatial.bounds.BoundingSphere; import org.openmali.spatial.bounds.Bounds; import org.openmali.vecmath2.Colorf; import org.openmali.vecmath2.Point3f; import org.openmali.vecmath2.Tuple3f; import org.xith3d.scenegraph.Appearance; import org.xith3d.scenegraph.ColoringAttributes; import org.xith3d.scenegraph.Geometry; import org.xith3d.scenegraph.PointArray; import org.xith3d.scenegraph.PointAttributes; import org.xith3d.scenegraph.Shape3D; import org.xith3d.scenegraph._SG_PrivilegedAccess; /** * This Shape represents a set of points in 3D-space. * Points are always drawn as real points on the screen. * * @author Marvin Froehlich (aka Qudus) */ public class Points extends Shape3D { public float minBoundsRadius = 0.1f; private float[] coords; private Tuple3f[] points; /** * {@inheritDoc} */ @Override public PointArray getGeometry() { return ( (PointArray)super.getGeometry() ); } /** * {@inheritDoc} */ @Override protected void updateBoundsCheap( boolean onlyDirty, boolean childrenToo, boolean parentToo, boolean onlyWorld ) { // if we already have the bounds then return if ( ( isIgnoreBounds() ) || ( !boundsDirty && onlyDirty ) ) { return; } if ( boundsAutoCompute && !onlyWorld ) { final Geometry geom = this.getGeometry(); if ( geom != null ) { if ( ( geom.isBoundsDirty() ) || ( !onlyDirty ) ) { final Bounds b = _SG_PrivilegedAccess.getCachedBounds( geom ); final BoundingSphere bsph; if ( b == null ) bsph = new BoundingSphere(); else bsph = (BoundingSphere)b; bsph.compute( geom ); if ( bsph.getRadius() < minBoundsRadius ) bsph.setRadius( minBoundsRadius ); _SG_PrivilegedAccess.setCachedBounds( bsph, geom ); } untransformedBounds.set( _SG_PrivilegedAccess.getCachedBounds( geom ) ); bounds.set( _SG_PrivilegedAccess.getCachedBounds( geom ) ); } } super.updateBoundsCheap( onlyDirty, childrenToo, parentToo, onlyWorld ); } /** * Sets this Points' coordinates * * @param points a Tuple3f-array containing the points' coordinates */ private void setCoordinates() { if ( ( this.coords == null ) || ( this.coords.length != points.length ) ) { this.coords = new float[ points.length * 3 ]; } for ( int i = 0; i < points.length; i++ ) { this.coords[ i * 3 + 0 ] = points[ i ].getX(); this.coords[ i * 3 + 1 ] = points[ i ].getY(); this.coords[ i * 3 + 2 ] = points[ i ].getZ(); } getGeometry().setCoordinates( 0, coords ); setBoundsDirty(); } /** * Sets this Points' coordinates * * @param points a Tuple3f-array containing the points' coordinates */ public void setCoordinates( Tuple3f[] points ) { this.points = points; setCoordinates(); } /** * Sets this Point's coordinates * * @param point a Tuple3f containing the point's coordinates */ public void setCoordinates( Tuple3f point ) { if ( this.points == null ) { this.points = new Tuple3f[] { new Point3f() }; } else if ( this.points.length != 1 ) { this.points = new Tuple3f[] { new Point3f() }; } this.points[ 0 ].set( point ); setCoordinates(); } /** * @return this Line's coordinates */ public Tuple3f[] getCoordinates() { return ( points ); } /** * @return this Line's coordinates */ public Tuple3f getPoint() { if ( points == null ) throw new NullPointerException( "This PointArray doesn't contain any coordinates." ); if ( points.length != 1 ) throw new UnsupportedOperationException( "This PointArray consists of more than one point." ); return ( points[ 0 ] ); } /** * Sets the Point's color * * @param color the new color */ public void setColor( Colorf color ) { getAppearance().getColoringAttributes().setColor( color ); if ( color.hasAlpha() ) getAppearance().getTransparencyAttributes( true ).setTransparency( color.getAlpha() ); else getAppearance().setTransparencyAttributes( null ); } /** * @return the Line's color */ public Colorf getColor() { return ( getAppearance().getColoringAttributes().getColor() ); } /** * Sets the Points' size in pixels * * @param size the new point-size in pixels */ public void setSize( float size ) { getAppearance().getPointAttributes().setPointSize( size ); } /** * @return the Points' size in pixels */ public float getSize() { return ( getAppearance().getPointAttributes().getPointSize() ); } /** * Sets the Points' antialiasing flag to enabled * * @param enabled */ public void setAntialiasingEnabled( boolean enabled ) { getAppearance().getPointAttributes().setPointAntialiasingEnabled( enabled ); } /** * @return the value of the Points' antialiasing flag */ public boolean isAntialiasingEnabled() { return ( getAppearance().getPointAttributes().isPointAntialiasingEnabled() ); } /** * Creates a new Points instance * * @param points the points' coordinates * @param size the points' size in pixels * @param antiAliasing the value of the points' antialiasing flag * @param color the points' color * * @see PointAttributes */ public Points( Tuple3f[] points, float size, boolean antiAliasing, Colorf color ) { super(); final boolean ib = isIgnoreBounds(); setIgnoreBounds( true ); setGeometry( new PointArray( points.length ) ); setIgnoreBounds( ib ); setCoordinates( points ); setAppearance( new Appearance() ); ColoringAttributes ca = new ColoringAttributes(); ca.setShadeModel( ColoringAttributes.SHADE_FLAT ); getAppearance().setColoringAttributes( ca ); setColor( color ); getAppearance().setPointAttributes( new PointAttributes() ); setSize( size ); setAntialiasingEnabled( antiAliasing ); updateBounds( true ); } /** * Creates a new Points instance * * @param points the points' coordinates * @param size the points' size in pixels * @param color the points' color * * @see PointAttributes */ public Points( Tuple3f[] points, float size, Colorf color ) { this( points, size, false, color ); } /** * Creates a new Points instance * * @param point the point's coordinates * @param size the points' size in pixels * @param antiAliasing the value of the points' antialiasing flag * @param color the points' color * * @see PointAttributes */ public Points( Tuple3f point, float size, boolean antiAliasing, Colorf color ) { this( new Tuple3f[] { point }, size, antiAliasing, color ); } /** * Creates a new Points instance * * @param point the point's coordinates * @param size the points' size in pixels * @param color the points' color * * @see PointAttributes */ public Points( Tuple3f point, float size, Colorf color ) { this( point, size, false, color ); } }