Package com.ardor3d.renderer.queue

Source Code of com.ardor3d.renderer.queue.AbstractRenderBucket

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.renderer.queue;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Stack;

import com.ardor3d.math.Vector3;
import com.ardor3d.math.type.ReadOnlyVector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.scenegraph.Spatial;
import com.ardor3d.util.SortUtil;

public class AbstractRenderBucket implements RenderBucket {

    protected Comparator<Spatial> _comparator;

    protected Spatial[] _currentList, _tempList;
    protected int _currentListSize;

    protected Stack<Spatial[]> _listStack = new Stack<Spatial[]>();
    protected Stack<Spatial[]> _listStackPool = new Stack<Spatial[]>();
    protected Stack<Integer> _listSizeStack = new Stack<Integer>();

    public AbstractRenderBucket() {
        _currentList = new Spatial[32];
        _tempList = new Spatial[_currentList.length];
    }

    public void add(final Spatial spatial) {
        spatial._queueDistance = Double.NEGATIVE_INFINITY;
        if (_currentListSize >= _currentList.length) {
            // grow if necessary
            final Spatial[] temp = new Spatial[_currentListSize * 2];
            System.arraycopy(_currentList, 0, temp, 0, _currentListSize);
            _currentList = temp;
            if (_tempList.length < temp.length) {
                _tempList = new Spatial[temp.length];
            }
        }
        _currentList[_currentListSize++] = spatial;
    }

    public void remove(final Spatial spatial) {
        int index = 0;
        for (int i = 0; i < _currentListSize; i++) {
            if (_currentList[index] == spatial) {
                break;
            }
            index++;
        }
        for (int i = index; i < _currentListSize - 1; i++) {
            _currentList[i] = _currentList[i + 1];
        }

        _currentListSize--;
    }

    public void clear() {
        if (_currentListSize > 0) {
            Arrays.fill(_currentList, 0, _currentListSize, null);
            _currentListSize = 0;
        }
    }

    public void render(final Renderer renderer) {
        for (int i = 0; i < _currentListSize; i++) {
            _currentList[i].draw(renderer);
        }
    }

    public void sort() {
        // only sort if we have more than one item in our bucket.
        if (_currentListSize > 1) {
            if (_currentListSize <= SortUtil.SHELL_SORT_THRESHOLD) {
                // shell sort
                SortUtil.shellSort(_currentList, 0, _currentListSize - 1, _comparator);
            } else {
                // copy in our list for use in the merge sort.
                System.arraycopy(_currentList, 0, _tempList, 0, _currentListSize);

                // merge sort
                SortUtil.msort(_tempList, _currentList, 0, _currentListSize - 1, _comparator);

                // null fill to remove references
                Arrays.fill(_tempList, 0, _currentListSize, null);
            }
        }
    }

    public void pushBucket() {
        _listStack.push(_currentList);
        if (_listStackPool.isEmpty()) {
            _currentList = new Spatial[32];
        } else {
            _currentList = _listStackPool.pop();
        }

        _listSizeStack.push(_currentListSize);
        _currentListSize = 0;
    }

    public void popBucket() {
        if (_currentList != null) {
            _listStackPool.push(_currentList);
        }
        _currentList = _listStack.pop();
        _currentListSize = _listSizeStack.pop();
    }

    /**
     * Calculates the distance from a spatial to the camera. Distance is a squared distance.
     *
     * @param spat
     *            Spatial to check distance.
     * @return Distance from Spatial to current context's camera.
     */
    protected double distanceToCam(final Spatial spat) {
        if (spat._queueDistance != Double.NEGATIVE_INFINITY) {
            return spat._queueDistance;
        }

        final Camera cam = Camera.getCurrentCamera();

        if (spat.getWorldBound() != null && Vector3.isValid(spat.getWorldBound().getCenter())) {
            spat._queueDistance = spat.getWorldBound().distanceToEdge(cam.getLocation());
        } else {
            final ReadOnlyVector3 spatPosition = spat.getWorldTranslation();
            if (!Vector3.isValid(spatPosition)) {
                spat._queueDistance = Double.POSITIVE_INFINITY;
            } else {
                spat._queueDistance = cam.getLocation().distance(spatPosition);
            }
        }

        return spat._queueDistance;
    }

}
TOP

Related Classes of com.ardor3d.renderer.queue.AbstractRenderBucket

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.