/**
* 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.terrain;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Mathias 'cylab' Henze
*/
@SuppressWarnings("unchecked")
public class DefaultGridResourceProvider implements GridResourceProvider
{
private List<GridResourceSpec> samplerSpecs;
private List<GridResourceSpec> surfaceSpecs;
protected DefaultGridResourceProvider()
{
}
public DefaultGridResourceProvider(List<GridResourceSpec<GridSampler>> samplerSpecs, List<GridResourceSpec<GridSurface>> surfaceSpecs)
{
this.samplerSpecs= new ArrayList<GridResourceSpec>(samplerSpecs);
this.surfaceSpecs= new ArrayList<GridResourceSpec>(surfaceSpecs);
}
protected void setSamplerSpecs( List<GridResourceSpec> samplerSpecs )
{
this.samplerSpecs = samplerSpecs;
}
protected void setSurfaceSpecs( List<GridResourceSpec> surfaceSpecs )
{
this.surfaceSpecs = surfaceSpecs;
}
public final GridSampler findSampler( float s1, float t1, float s2, float t2, int detail )
{
GridResourceSpec<GridSampler> spec = findResourceSpec(samplerSpecs, s1, t1, s2, t2, detail);
// if a specific detail level was loaded, we assume it is loaded by the Terrain LOD-System, so we need to adjust the refCount
if (detail != -1)
{
spec.addReference();
}
GridSampler sampler = spec.getCachedResource();
if (sampler == null)
{
sampler = createSampler(spec);
spec.setCachedResource(sampler);
}
return sampler;
}
public void releaseSampler( GridSampler sampler )
{
for(int i = 0; i < samplerSpecs.size(); i++)
{
GridResourceSpec spec= samplerSpecs.get(i);
// only release the sampler, when the spec is unreferenced (release() return true)
if(spec.getCachedResource() == sampler && spec.release())
{
sampler.release();
return;
}
}
}
public final GridSurface findSurface( float s1, float t1, float s2, float t2, int detail )
{
GridResourceSpec<GridSurface> spec = findResourceSpec(surfaceSpecs, s1, t1, s2, t2, detail);
// if a specific detail level was loaded, we assume it is loaded by the Terrain LOD-System, so we need to adjust the refCount
if (detail != -1)
{
spec.addReference();
}
GridSurface surface = spec.getCachedResource();
if (surface == null)
{
surface = createSurface(spec);
spec.setCachedResource(surface);
}
return surface;
}
public void releaseSurface( GridSurface surface )
{
for(int i = 0; i < surfaceSpecs.size(); i++)
{
GridResourceSpec spec= surfaceSpecs.get(i);
// only release the surface, when the spec is unreferenced (release() return true)
if(spec.getCachedResource() == surface && spec.release())
{
surface.release();
return;
}
}
}
protected GridResourceSpec findResourceSpec(List<GridResourceSpec> specs, float s1, float t1, float s2, float t2, int detail)
{
int handle= 0; // if no matching spec is found, just use the first one
int matches[]= new int[32];
if(detail>31) detail= 31;
// first find matching ResurceSpec regardless of the detail level
for(int i = 0; i < specs.size(); i++)
{
GridResourceSpec spec= specs.get(i);
if(s1>=spec.getS1() && s2<=spec.getS2() && t1>=spec.getT1() && t2<=spec.getT2())
{
if(detail==-1 && spec.getCachedResource()==null) continue;
int specDetail= spec.getDetail();
if(specDetail>31) specDetail= 31;
matches[spec.getDetail()]= i+1; // mark handle valid by avoiding 0
}
}
// find the best valid spec by backward searching through the valid detail levels
for(int i = detail==-1?31:detail; i >= 0; i--)
{
if( matches[i] > 0 )
{
handle = matches[i] - 1; // remove the validity mark
break;
}
}
return specs.get(handle);
}
protected GridSampler createSampler(GridResourceSpec<GridSampler> spec)
{
try
{
return new HeightMapSampler( spec );
}
catch( Exception ex )
{
Logger.getLogger( DefaultGridResourceProvider.class.getName() ).log( Level.SEVERE, null, ex );
}
return null;
}
protected GridSurface createSurface(GridResourceSpec<GridSurface> spec)
{
try
{
return new TextureSurface(spec);
}
catch( Exception ex )
{
Logger.getLogger( DefaultGridResourceProvider.class.getName() ).log( Level.SEVERE, null, ex );
}
return null;
}
}