Revision: 493 http://skycastle.svn.sourceforge.net/skycastle/?rev=493&view=rev Author: zzorn Date: 2008-04-28 11:34:37 -0700 (Mon, 28 Apr 2008) Log Message: ----------- Now the stroke is rendered continuous when you move the pen. There are still a lot of innefficiencies though, probably we'll use fixed length stroke sections combined with rendering the stroke to a texture when it is completed. That would still allow the stroke to morph while it is being drawn, allowing effects that work on a complete stroke, and not just on a stroke so far. Modified Paths: -------------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/Stroke.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeImpl.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeListener.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/rendering/StrokeRenderer.java Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java 2008-04-28 07:19:44 UTC (rev 492) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java 2008-04-28 18:34:37 UTC (rev 493) @@ -489,11 +489,7 @@ { final Stroke stroke = (Stroke) groupElement; - // TODO: add capability to render points. - if ( stroke.getPoints().size() >= 2 ) - { - myRoot3DNode.attachChild( new StrokeRenderer( stroke ) ); - } + myRoot3DNode.attachChild( new StrokeRenderer( stroke ) ); } else if ( groupElement instanceof Group ) { Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/Stroke.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/Stroke.java 2008-04-28 07:19:44 UTC (rev 492) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/Stroke.java 2008-04-28 18:34:37 UTC (rev 493) @@ -1,13 +1,12 @@ package org.skycastle.sketch.model.stroke; -import org.skycastle.sketch.model.group.Group; import org.skycastle.sketch.model.group.GroupElement; import org.skycastle.sketch.sample.DataSample; import java.util.List; /** - * A brush stroke that is defined by a path of {@link StrokePoint}s. + * A brush stroke that is defined by a path of {@link DataSample}s. * * @author Hans Häggström */ @@ -23,27 +22,22 @@ void addPoint( DataSample addedPoint ); /** - * Removes the specified {@link DataSample} from this {@link Stroke}. - * - * @param removedPoint should not be null, and should be present. - */ - void removePoint( DataSample removedPoint ); - - /** * @return a read-only list with the {@link DataSample}s in this {@link Stroke}. */ List<DataSample> getPoints(); /** - * @return the {@link StrokeListener} that is currently listening to changes to this {@link Stroke}. + * Adds the specified StrokeListener. + * + * @param addedStrokeListener a listener that will be notified about added points in the stroke. Should not be null or already added. */ - StrokeListener getStrokeListener(); + void addStrokeListener( StrokeListener addedStrokeListener ); /** - * Usually this is only called from the {@link Group} that contains the {@link Stroke}. + * Removes the specified StrokeListener. * - * @param strokeListener the {@link StrokeListener} that should listen to changes to this {@link Stroke}. + * @param removedStrokeListener the listener to remove. Should not be null, and should be present. */ - void setStrokeListener( StrokeListener strokeListener ); + void removeStrokeListener( StrokeListener removedStrokeListener ); } Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeImpl.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeImpl.java 2008-04-28 07:19:44 UTC (rev 492) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeImpl.java 2008-04-28 18:34:37 UTC (rev 493) @@ -6,7 +6,9 @@ import org.skycastle.util.listenable.collection.list.ListenableArrayList; import org.skycastle.util.listenable.collection.list.ListenableMutableList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * @author Hans Haggstrom @@ -22,7 +24,7 @@ private final ListenableMutableList<DataSample> myPoints = new ListenableArrayList<DataSample>( INITIAL_POINT_CAPACITY ); - private StrokeListener myStrokeListener; + private Set<StrokeListener> myStrokeListeners = new HashSet<StrokeListener>( 3 ); //====================================================================== // Private Constants @@ -42,42 +44,33 @@ myPoints.add( addedPoint ); - if ( myStrokeListener != null ) + for ( StrokeListener strokeListener : myStrokeListeners ) { - myStrokeListener.onPointAdded( this, addedPoint ); + strokeListener.onPointAdded( this, addedPoint ); } } - public void removePoint( final DataSample removedPoint ) - { - ParameterChecker.checkNotNull( removedPoint, "removedPoint" ); - ParameterChecker.checkContained( removedPoint, myPoints, "myPoints" ); - - myPoints.remove( removedPoint ); - - if ( myStrokeListener != null ) - { - myStrokeListener.onPointRemoved( this, removedPoint ); - } - } - - public List<DataSample> getPoints() { return myPoints.getReadOnlyList(); } - public StrokeListener getStrokeListener() + public void addStrokeListener( StrokeListener addedStrokeListener ) { - return myStrokeListener; + ParameterChecker.checkNotNull( addedStrokeListener, "addedStrokeListener" ); + ParameterChecker.checkNotAlreadyContained( addedStrokeListener, myStrokeListeners, "myStrokeListeners" ); + + myStrokeListeners.add( addedStrokeListener ); } - - public void setStrokeListener( final StrokeListener strokeListener ) + public void removeStrokeListener( StrokeListener removedStrokeListener ) { - myStrokeListener = strokeListener; + ParameterChecker.checkNotNull( removedStrokeListener, "removedStrokeListener" ); + ParameterChecker.checkContained( removedStrokeListener, myStrokeListeners, "myStrokeListeners" ); + + myStrokeListeners.remove( removedStrokeListener ); } } Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeListener.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeListener.java 2008-04-28 07:19:44 UTC (rev 492) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/model/stroke/StrokeListener.java 2008-04-28 18:34:37 UTC (rev 493) @@ -11,19 +11,12 @@ { /** - * Called when a point is added to a {@link Stroke}. + * Called when a point is added to the end of a {@link Stroke}. * * @param stroke the {@link Stroke} in question. * @param point the point in question. */ void onPointAdded( Stroke stroke, DataSample point ); - /** - * Called when a point is removed from a {@link Stroke}. - * - * @param stroke the {@link Stroke} in question. - * @param point the point in question. - */ - void onPointRemoved( Stroke stroke, DataSample point ); } Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/rendering/StrokeRenderer.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/rendering/StrokeRenderer.java 2008-04-28 07:19:44 UTC (rev 492) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/rendering/StrokeRenderer.java 2008-04-28 18:34:37 UTC (rev 493) @@ -17,6 +17,7 @@ import com.jme.util.geom.BufferUtils; import com.jmex.awt.swingui.ImageGraphics; import org.skycastle.sketch.model.stroke.Stroke; +import org.skycastle.sketch.model.stroke.StrokeListener; import org.skycastle.sketch.sample.DataSample; import org.skycastle.util.ImageUtils; import org.skycastle.util.ParameterChecker; @@ -44,19 +45,20 @@ private final Stroke myStroke; private final float myZ; - private final FloatBuffer myVertexes; - private final FloatBuffer myColors; - private final FloatBuffer myTextureCoordinates; - private final FloatBuffer myNormals; - private final IntBuffer myIndices; - private final int myNumberOfVertices; - private final int myNumberOfIndices; private final Object myTextureStateLock = new Object(); - private final int myNumberOfPoints; - private final int myNumberOfSegments; - private final int myNumberOfTriangles; + private FloatBuffer myVertexes; + private FloatBuffer myColors; + private FloatBuffer myTextureCoordinates; + private FloatBuffer myNormals; + private IntBuffer myIndices; + private int myNumberOfVertices; + private int myNumberOfIndices; + private int myNumberOfPoints; + private int myNumberOfSegments; + private int myNumberOfTriangles; + private TextureState myTextureState; private Texture myTexture; private ImageGraphics myTextureGraphics; @@ -121,27 +123,21 @@ myStroke = stroke; myZ = z; - // Calculate sizes - myNumberOfPoints = myStroke.getPoints().size(); - myNumberOfSegments = myNumberOfPoints - 1; - myNumberOfTriangles = myNumberOfSegments * NUMBER_OF_TRIANGLES_PER_SEGMENT; - myNumberOfVertices = myNumberOfPoints * 3; - myNumberOfIndices = myNumberOfSegments * NUMBER_OF_INDICES_IN_SEGMENT; + myStroke.addStrokeListener( new StrokeListener() + { - // Create databuffers - myVertexes = BufferUtils.createVector3Buffer( myNumberOfVertices ); - myColors = BufferUtils.createColorBuffer( myNumberOfVertices ); - myTextureCoordinates = BufferUtils.createVector2Buffer( myNumberOfVertices ); - myNormals = BufferUtils.createVector3Buffer( myNumberOfVertices ); - myIndices = BufferUtils.createIntBuffer( myNumberOfIndices ); + public void onPointAdded( final Stroke updatedStroke, final DataSample point ) + { + recalculateStroke(); + } - // Stich together the vertices into triangles - initializeIndices(); + } ); + if ( stroke.getPoints().size() >= 2 ) + { + recalculateStroke(); + } - updateBounds(); - - GameTaskQueueManager.getManager().getQueue( GameTaskQueue.UPDATE ).enqueue( new Callable<Object>() { @@ -233,6 +229,28 @@ //====================================================================== // Private Methods + private void recalculateStroke() + { + // Calculate sizes + myNumberOfPoints = myStroke.getPoints().size(); + myNumberOfSegments = myNumberOfPoints - 1; + myNumberOfTriangles = myNumberOfSegments * NUMBER_OF_TRIANGLES_PER_SEGMENT; + myNumberOfVertices = myNumberOfPoints * 3; + myNumberOfIndices = myNumberOfSegments * NUMBER_OF_INDICES_IN_SEGMENT; + + // Create databuffers + myVertexes = BufferUtils.createVector3Buffer( myNumberOfVertices ); + myColors = BufferUtils.createColorBuffer( myNumberOfVertices ); + myTextureCoordinates = BufferUtils.createVector2Buffer( myNumberOfVertices ); + myNormals = BufferUtils.createVector3Buffer( myNumberOfVertices ); + myIndices = BufferUtils.createIntBuffer( myNumberOfIndices ); + + // Stich together the vertices into triangles + initializeIndices(); + + + updateBounds(); + } /* public void setPlaceholderTexture( final Texture texture, final BoundingRectangle textureArea ) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.