Package com.ardor3d.extension.interact.widget

Source Code of com.ardor3d.extension.interact.widget.InteractRing

/**
* 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.extension.interact.widget;

import java.io.IOException;
import java.nio.FloatBuffer;

import com.ardor3d.image.Texture2D;
import com.ardor3d.math.MathUtils;
import com.ardor3d.renderer.IndexMode;
import com.ardor3d.renderer.state.RenderState;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.FloatBufferData;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.util.export.InputCapsule;
import com.ardor3d.util.export.OutputCapsule;
import com.ardor3d.util.geom.BufferUtils;

/**
* Textured ring geometry, intended for use as a rotational handle.
*/
public class InteractRing extends Mesh {
    protected float _innerRadius, _outerRadius;
    protected int _tessRings = 2;
    protected int _tessSteps = 32;
    protected float _texMul = 4.0f;
    protected float _concaveValue = 0;

    public InteractRing() {}

    public InteractRing(final String name, final int tessRings, final int tessSteps, final float radius,
            final float width) {
        this(name, tessRings, tessSteps, radius, width, 0);
    }

    public InteractRing(final String name, final int tessRings, final int tessSteps, final float radius,
            final float width, final float concaveValue) {
        super(name);
        _tessRings = tessRings;
        _tessSteps = tessSteps;
        _concaveValue = concaveValue;
        setRadius(radius, width);
    }

    public void setRadius(final float radius, final float width) {
        _innerRadius = radius;
        _outerRadius = radius + width;
        updateGeometry();
    }

    /**
     * @param vMult
     *            new multiplier for v direction of texture coords (around ring)
     */
    public void setTextureMultiplier(final float vMult) {
        _texMul = vMult;
        updateGeometry();
    }

    public void setConcaveValue(final float value) {
        _concaveValue = value;
        updateGeometry();
    }

    /**
     * Convenience method for setting texture without managing TextureState.
     *
     * @param texture
     *            the new texture to set on unit 0.
     */
    public void setTexture(final Texture2D texture) {
        TextureState ts = (TextureState) getLocalRenderState(RenderState.StateType.Texture);
        if (ts == null) {
            ts = new TextureState();
            ts.setEnabled(true);
            setRenderState(ts);
        }
        ts.setTexture(texture, 0);
    }

    /**
     *
     */
    public void updateGeometry() {
        final int numPairs = _tessSteps + 1;
        final int totalVerts = _tessRings * numPairs * 2;

        FloatBuffer crdBuf = getMeshData().getVertexBuffer();
        if (crdBuf == null || totalVerts != crdBuf.limit() / 3) { // allocate new buffers
            getMeshData().setVertexBuffer(BufferUtils.createFloatBuffer(totalVerts * 3));
            getMeshData().setNormalBuffer(BufferUtils.createFloatBuffer(totalVerts * 3));
            getMeshData().setTextureCoords(new FloatBufferData(BufferUtils.createFloatBuffer(totalVerts * 2), 2), 0);
            crdBuf = getMeshData().getVertexBuffer();
        }
        final FloatBuffer nrmBuf = getMeshData().getNormalBuffer();
        final FloatBufferData tc = getMeshData().getTextureCoords(0);
        final FloatBuffer txcBuf = tc.getBuffer();
        calculateVertexData(_tessRings, numPairs, totalVerts, crdBuf, nrmBuf, txcBuf);

        updateModelBound();
    }

    protected void normalize(final int i, final float[] nrm) {
        final float length = (float) MathUtils
                .sqrt(nrm[i] * nrm[i] + nrm[i + 1] * nrm[i + 1] + nrm[i + 2] * nrm[i + 2]);
        nrm[i] /= length;
        nrm[i + 1] /= length;
        nrm[i + 2] /= length;
    }

    protected void calculateVertexData(final int numStrips, final int numPairs, final int totalVerts,
            final FloatBuffer crdBuf, final FloatBuffer nrmBuf, final FloatBuffer txcBuf) {
        // we are generating strips
        getMeshData().setIndexMode(IndexMode.TriangleStrip);

        final float astep = (float) (Math.PI * 2 / _tessSteps);
        final float sstep = 1.0f / numStrips;
        final float rrange = _outerRadius - _innerRadius;
        final float rstep = rrange / numStrips;
        float xa, ya;
        float r0, r1;
        float nadd0, nadd1;
        float tc;
        final float up = 1;
        final float[] nrm = new float[6];
        crdBuf.rewind();
        nrmBuf.rewind();
        txcBuf.rewind();
        for (int s = 0; s < numStrips; s++) {
            nadd0 = _concaveValue * (s + 0 - numStrips * 0.5f) / numStrips;
            nadd1 = _concaveValue * (s + 1 - numStrips * 0.5f) / numStrips;
            for (int a = 0; a < numPairs; a++) {
                xa = (float) Math.cos(a * astep);
                ya = (float) Math.sin(a * astep);
                r0 = _innerRadius + (s + 0) * rstep;
                r1 = _innerRadius + (s + 1) * rstep;

                crdBuf.put(xa * r0).put(ya * r0).put(0);
                crdBuf.put(xa * r1).put(ya * r1).put(0);

                nrm[0] = nadd0 * xa;
                nrm[1] = nadd0 * ya;
                nrm[2] = up;
                nrm[3] = nadd1 * xa;
                nrm[4] = nadd1 * ya;
                nrm[5] = up;
                normalize(0, nrm);
                normalize(3, nrm);
                nrmBuf.put(nrm[0]).put(nrm[1]).put(nrm[2]);
                nrmBuf.put(nrm[3]).put(nrm[4]).put(nrm[5]);

                tc = a * _texMul / _tessSteps;
                txcBuf.put((s + 0) * sstep).put(tc);
                txcBuf.put((s + 1) * sstep).put(tc);
            }
        }
    }

    @Override
    public void write(final OutputCapsule capsule) throws IOException {
        super.write(capsule);
        capsule.write(_innerRadius, "innerRadius", 0f);
        capsule.write(_outerRadius, "outerRadius", 0f);
        capsule.write(_tessRings, "tessRings", 2);
        capsule.write(_tessSteps, "tessSteps", 16);
        capsule.write(_texMul, "texMul", 1f);
        capsule.write(_concaveValue, "concaveValue", 0f);
    }

    @Override
    public void read(final InputCapsule capsule) throws IOException {
        super.read(capsule);
        _innerRadius = capsule.readFloat("innerRadius", 0f);
        _outerRadius = capsule.readFloat("outerRadius", 0f);
        _tessRings = capsule.readInt("tessRings", 2);
        _tessSteps = capsule.readInt("tessSteps", 16);
        _texMul = capsule.readFloat("texMul", 1f);
        _concaveValue = capsule.readFloat("concaveValue", 0f);
    }
}
TOP

Related Classes of com.ardor3d.extension.interact.widget.InteractRing

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.