/**
* 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.render.preprocessing.sorting;
import java.util.Comparator;
import org.xith3d.render.preprocessing.OrderedState;
import org.xith3d.render.preprocessing.RenderAtom;
import org.xith3d.render.preprocessing.RenderBin;
import org.xith3d.render.preprocessing.RenderBin.DynamicAtomArray;
import org.xith3d.render.states.StateSortable;
import org.xith3d.render.states.StateSortableMap;
import org.xith3d.scenegraph.Transform3D;
import org.xith3d.utility.comparator.Sorter;
/**
* This sorter sorts RenderAtoms by StateUnits (state-sorting)
* with respect to the Node's {@link OrderedState}.
*
* @author YVG
* @author Marvin Froehlich (aka Qudus)
*/
public class OrderedStateRenderBinSorter extends RenderBinSorter implements Comparator< RenderAtom< ? > >
{
private final StatePriorities priorities;
public final StatePriorities getPriorities()
{
return ( priorities );
}
/**
* {@inheritDoc}
*/
public int compare( RenderAtom< ? > atom1, RenderAtom< ? > atom2 )
{
// In case of Shapes in a SharedGroup and Links...
if ( atom1 == atom2 )
return ( 0 );
final int stateType1 = atom1.getStateType();
final int stateType2 = atom2.getStateType();
if ( stateType1 < stateType2 )
return ( -1 );
else if ( stateType1 > stateType2 )
return ( 1 );
if ( atom1.getSortableStates().hash == atom2.getSortableStates().hash )
return ( 0 );
/*
* Check the ordered status.
* This needs to be done outside the shader loop
* or else it is doing a redundent check every iteration.
*/
final OrderedState os1 = atom1.getOrderedState();
final OrderedState os2 = atom2.getOrderedState();
if ( os1 != os2 )
{
if ( os1 == null )
return ( -1 );
else if ( os2 == null )
return ( +1 );
// ok if we get there then both shapes are
// in ordered groups, so we need to compare their
// ordered states
int index = 0;
while ( ( index < os1.depth ) && ( index < os2.depth ) )
{
if ( os1.orderIds[ index ] < os2.orderIds[ index ] )
return ( -1 );
else if ( os1.orderIds[ index ] > os2.orderIds[ index ] )
return ( +1 );
index++;
}
// ok so all the states matched for the minimum depth
// of their relative state, so the one with less depth
// goes first
if ( os1.depth < os2.depth )
return ( -1 );
else if ( os1.depth > os2.depth )
return ( +1 );
// if we get here then they are exactly the same but for
// insane reason the OrderState objects are not the same...
throw new Error( "Completely impossible order state condition (comparing " + os1 + " and " + os2 + ")" );
}
// if we get here then we need to sort based on the state priorities
final StateSortableMap ssMap1 = atom1.getSortableStates();
final StateSortableMap ssMap2 = atom2.getSortableStates();
for ( int i = 0; i < priorities.numStatePriorities; i++ )
{
// check the states
final int prio = priorities.statePriorities[ i ];
final StateSortable ss1 = ssMap1.map[ prio ];
final StateSortable ss2 = ssMap2.map[ prio ];
if ( ss1 == ss2 )
continue;
if ( ss1 == null )
return ( -1 );
else if ( ss2 == null )
return ( +1 );
final long bid1 = ssMap1.mapID[ prio ];
final long bid2 = ssMap2.mapID[ prio ];
if ( bid1 < bid2 )
return ( -1 );
else if ( bid1 > bid2 )
return ( +1 );
}
return ( 0 );
}
@Override
public boolean equals( Object o )
{
return ( false );
}
/**
* {@inheritDoc}
*/
@Override
public void sortRenderBin( RenderBin renderBin, Transform3D viewTransform )
{
final DynamicAtomArray atoms = renderBin.getAtoms();
// Arrays.sort( atoms.getRawArray(), 0, atoms.size(), this );
Sorter.quickSort( atoms.getRawArray(), 0, atoms.size() - 1, this );
// head = Sorter.mergeSort( head, this );
}
public OrderedStateRenderBinSorter( StatePriorities priorities )
{
this.priorities = priorities;
}
public OrderedStateRenderBinSorter()
{
this( StatePriorities.getDefaultPriorities() );
}
}