/**
* 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.loaders.models.util.specific;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.xith3d.loaders.models.Model;
import org.xith3d.loaders.models.ModelLoader;
import org.xith3d.loaders.models.animations.ModelAnimation;
import org.xith3d.loaders.models.animations.PrecomputedAnimationKeyFrame;
import org.xith3d.loaders.models.animations.PrecomputedAnimationKeyFrameController;
import org.xith3d.scenegraph.Geometry;
import org.xith3d.scenegraph.Shape3D;
/**
* Utility methods for OBJ models.
*
* @author Marvin Froehlich (aka Qudus)
*/
public class OBJTools
{
private static Model loadOBJFrames( ModelLoader loader, final String baseURL, ArrayList<Geometry[]> frames )
{
Model baseModel = null;
int frameCount = -1;
for ( int i = 1; i < Integer.MAX_VALUE; i++ )
{
// Find file name
String num = Integer.toString( i );
final float length = num.length();
for ( int j = 0; j < 6 - length; j++ )
{
num = "0" + num;
}
final String frameURL = baseURL + "_" + num + ".obj";
try
{
Model frameModel = loader.loadModel( new URL( frameURL ) );
if ( i == 1 )
{
baseModel = frameModel;
if ( baseModel.getShapesCount() == 0 )
{
System.err.println( "Incorrectly loaded file : " + frameURL );
}
}
if ( frameModel.getShapesCount() != baseModel.getShapesCount() )
{
throw new Error( "Incorrectly loaded file : " + frameURL );
}
Geometry[] geoms = new Geometry[ frameModel.getShapesCount() ];
for ( int j = 0; j < frameModel.getShapesCount(); j++ )
{
geoms[j] = frameModel.getShape( j ).getGeometry();
}
frames.add( geoms );
}
catch ( final FileNotFoundException e )
{
if ( frameCount == -1 )
{
e.printStackTrace();
}
// If file not found it means we got to the end of the anim
return ( baseModel );
}
catch ( final IOException e )
{
if ( frameCount == -1 )
{
e.printStackTrace();
}
// If file not found it means we got to the end of the anim
return ( baseModel );
}
// If loaded successfully, maybe one more ?
frameCount++;
}
return ( baseModel );
}
public static Model loadPrecomputedModel( URL url )
{
ArrayList<Geometry[]> frames = new ArrayList<Geometry[]>();
if ( url.toExternalForm().endsWith( ".amo" ) )
{
try
{
BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream() ) );
String objFileName = reader.readLine();
objFileName = url.toExternalForm().substring( 0, url.toExternalForm().lastIndexOf( "/" ) ) + "/" + objFileName;
Model baseModel = loadOBJFrames( ModelLoader.getInstance(), objFileName, frames );
ArrayList<ModelAnimation> anims = new ArrayList<ModelAnimation>();
String line;
while ( ( line = reader.readLine() ) != null )
{
StringTokenizer tokenizer = new StringTokenizer( line );
String animName = tokenizer.nextToken();
int from = Integer.valueOf( tokenizer.nextToken() );
int to = Integer.valueOf( tokenizer.nextToken() );
/* boolean loop = (Integer.valueOf( */tokenizer.nextToken()/* * ) == 1)*/;
int numFrames = to - from + 1;
PrecomputedAnimationKeyFrameController[] controllers = new PrecomputedAnimationKeyFrameController[ baseModel.getShapesCount() ];
for ( int i = 0; i < baseModel.getShapesCount(); i++ )
{
Shape3D shape = baseModel.getShape( i );
PrecomputedAnimationKeyFrame[] keyFrames = new PrecomputedAnimationKeyFrame[ numFrames ];
int k = 0;
for ( int j = from; j <= to; j++ )
{
keyFrames[k++] = new PrecomputedAnimationKeyFrame( frames.get( j )[i] );
}
controllers[i] = new PrecomputedAnimationKeyFrameController( keyFrames, shape );
}
anims.add( new ModelAnimation( animName, numFrames, 25f, controllers ) );
}
baseModel.setAnimations( anims.toArray( new ModelAnimation[ anims.size() ] ) );
return ( baseModel );
}
catch ( FileNotFoundException e )
{
e.printStackTrace();
return ( null );
}
catch ( IOException e )
{
e.printStackTrace();
return ( null );
}
}
// not ".amo"!
{
Model baseModel = loadOBJFrames( ModelLoader.getInstance(), url.toExternalForm(), frames );
PrecomputedAnimationKeyFrameController[] controllers = new PrecomputedAnimationKeyFrameController[ baseModel.getShapesCount() ];
for ( int i = 0; i < baseModel.getShapesCount(); i++ )
{
Shape3D shape = baseModel.getShape( i );
PrecomputedAnimationKeyFrame[] keyFrames = new PrecomputedAnimationKeyFrame[ frames.size() ];
for ( int j = 0 ; j < frames.size(); j++ )
{
keyFrames[j] = new PrecomputedAnimationKeyFrame( frames.get( j )[i] );
}
controllers[i] = new PrecomputedAnimationKeyFrameController( keyFrames, shape );
}
ModelAnimation[] anims = new ModelAnimation[]
{
new ModelAnimation( "default", frames.size(), 25f, controllers )
};
baseModel.setAnimations( anims );
return ( baseModel );
}
}
public static Model loadPrecomputedModel( File file )
{
try
{
return ( loadPrecomputedModel( file.toURI().toURL() ) );
}
catch ( MalformedURLException e )
{
e.printStackTrace();
return ( null );
}
}
public static Model loadPrecomputedModel( String filename )
{
return ( loadPrecomputedModel( new File( filename ) ) );
}
}