lensflare.java

来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 436 行 · 第 1/2 页

JAVA
436
字号
/*
 * Copyright (c) 2003-2009 jMonkeyEngine
 * All rights reserved.
 *
 * 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 'jMonkeyEngine' 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) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jmex.effects;

import java.io.IOException;
import java.util.ArrayList;

import com.jme.intersection.BoundingPickResults;
import com.jme.intersection.PickResults;
import com.jme.math.Ray;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Geometry;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.TriMesh;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.RenderState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.export.InputCapsule;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.OutputCapsule;

/**
 * <code>LensFlare</code> Lens flare effect for jME. Notice that currently, it
 * doesn't do occlusion culling.
 * 
 * The easiest way to use this class is to use the LensFlareFactory to create
 * your LensFlare and then attach it as a child to a lightnode. Optionally you
 * can make it a child or a sibling of an object you wish to have a 'glint' on.
 * In the case of sibling, use
 * setLocalTranslation(sibling.getLocalTranslation()) or something similar to
 * ensure position.
 * 
 * Only FlareQuad objects are acceptable as children.
 * 
 * @author Joshua Slack
 * @version $Id: LensFlare.java,v 1.17 2007/10/27 19:36:40 renanse Exp $
 */

public class LensFlare extends Node {
    private static final long serialVersionUID = 1L;

    private Vector2f midPoint;

    private Vector3f flarePoint;

    private Vector3f scale = new Vector3f(1, 1, 1);
    
    private boolean triangleOcclusion = false;

    private Ray pickRay = new Ray();

    private float maxNotOccludedOffset;

    private float minNotOccludedOffset;

    private Ray secondRay = new Ray();

    private Vector2f secondScreenPos = new Vector2f();

    private Vector3f flaresWorldAxis = new Vector3f();

    private Vector2f screenPos = new Vector2f();

    private ArrayList<Integer> pickTriangles = new ArrayList<Integer>();

    private ArrayList<Geometry> pickBoundsGeoms = new ArrayList<Geometry>();

    private ArrayList<Geometry> occludingTriMeshes = new ArrayList<Geometry>();

    public LensFlare() {} 
    
    /**
     * Creates a new LensFlare node without FlareQuad children. Use attachChild
     * to attach FlareQuads.
     * 
     * @param name
     *            The name of the node.
     */
    public LensFlare(String name) {
        super(name);
        init();
    }

    /**
     * Init basic params of Lensflare...
     */
    private void init() {
        DisplaySystem display = DisplaySystem.getDisplaySystem();
        midPoint = new Vector2f(display.getWidth() >> 1,
                display.getHeight() >> 1);

        // Set the renderstates for lensflare to all defaults...
        for (int i = 0; i < RenderState.StateType.values().length; i++) {
            setRenderState(Renderer.defaultStateList[i]);
        }

        // Set a alpha blending state.
        BlendState as1 = display.getRenderer().createBlendState();
        as1.setBlendEnabled(true);
        as1.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
        as1.setDestinationFunction(BlendState.DestinationFunction.One);
        as1.setTestEnabled(true);
        as1.setTestFunction(BlendState.TestFunction.GreaterThan);
        as1.setEnabled(true);
        setRenderState(as1);

        setRenderQueueMode(Renderer.QUEUE_ORTHO);
        setLightCombineMode(Spatial.LightCombineMode.Off);
        setTextureCombineMode(TextureCombineMode.Replace);
    }

    /**
     * Get the flare's reference midpoint, usually the center of the screen.
     * 
     * @return Vector2f
     */
    public Vector2f getMidPoint() {
        return midPoint;
    }

    /**
     * Set the flare's reference midpoint, the center of the screen by default.
     * It may be useful to change this if the whole screen is not used for a
     * scene (for example, if part of the screen is taken up by a status bar.)
     * 
     * @param midPoint
     *            Vector2f
     */
    public void setMidPoint(Vector2f midPoint) {
        this.midPoint = midPoint;
    }

    /**
     * Query intensity of the flares.
     * 
     * @return current value of field intensity
     * @see #setIntensity(float)
     */
    public float getIntensity() {
        return this.intensity;
    }

    /**
     * store the value for field intensity.
     */
    private float intensity = 1;

    /**
     * Set intensity of the flare. Intensity 0 means flares are not visible, 1
     * means maximum size and opacity.
     * 
     * @param value
     *            new value between 0 and 1
     */
    public void setIntensity(final float value) {
        if (value > 1) {
            this.intensity = 1;
        } else if (value < 0) {
            this.intensity = 0;
        } else {
            this.intensity = value;
        }
    }

    /**
     * <code>onDraw</code> checks the node with the camera to see if it should
     * be culled, if not, the node's draw method is called.
     * 
     * @param r
     *            the renderer used for display.
     */
    public void onDraw(Renderer r) {
        DisplaySystem display = DisplaySystem.getDisplaySystem();
        midPoint.set(r.getWidth() >> 1, r.getHeight() >> 1);
        // Locate light src on screen x,y
        flarePoint = display.getScreenCoordinates(worldTranslation, flarePoint)
                .subtractLocal(midPoint.x, midPoint.y, 0);
        if (flarePoint.z >= 1.0f) { // if it's behind us
            setCullHint(Spatial.CullHint.Always);
            return;
        } 
            

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?