Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.dungeongame.gameclient.scene3d;
- /*
- * Copyright (c) 2009-2012 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.
- */
- import com.jme3.asset.AssetManager;
- import com.jme3.export.InputCapsule;
- import com.jme3.export.JmeExporter;
- import com.jme3.export.JmeImporter;
- import com.jme3.export.OutputCapsule;
- import com.jme3.light.Light;
- import com.jme3.light.LightList;
- import com.jme3.light.PointLight;
- import com.jme3.material.MatParam;
- import com.jme3.material.Material;
- import com.jme3.material.Technique;
- import com.jme3.math.FastMath;
- import com.jme3.math.Quaternion;
- import com.jme3.math.Vector2f;
- import com.jme3.math.Vector3f;
- import com.jme3.math.Vector4f;
- import com.jme3.renderer.Camera;
- import com.jme3.renderer.Caps;
- import com.jme3.renderer.RenderManager;
- import com.jme3.renderer.ViewPort;
- import com.jme3.renderer.queue.GeometryList;
- import com.jme3.renderer.queue.RenderQueue.ShadowMode;
- import com.jme3.scene.Geometry;
- import com.jme3.scene.Node;
- import com.jme3.shader.Shader;
- import com.jme3.shader.Uniform;
- import com.jme3.shader.VarType;
- import com.jme3.shadow.AbstractShadowRenderer;
- import com.jme3.shadow.CompareMode;
- import com.jme3.shadow.PointLightShadowRenderer;
- import com.jme3.shadow.ShadowUtil;
- import com.jme3.texture.FrameBuffer;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Comparator;
- public class MultiPointLightShadowRenderer extends MyAbstractShadowRenderer
- implements Comparator<PointLight>
- {
- public static final int CAM_NUMBER = 6;
- protected PointLight light;
- protected Camera[] shadowCams;
- private Geometry[] frustums = null;
- private float _sortTmp;
- private Node _lightNode;
- //private Camera _playerCam;
- /**
- * Used for serialization use
- * PointLightShadowRenderer"PointLightShadowRenderer(AssetManager
- * assetManager, int shadowMapSize)
- */
- public MultiPointLightShadowRenderer()
- {
- super();
- //_lights = new ArrayList<PointLight>();
- }
- /**
- * Creates a PointLightShadowRenderer
- *
- * @param assetManager the application asset manager
- * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
- * etc...)
- */
- public MultiPointLightShadowRenderer(AssetManager assetManager, int shadowMapSize, Node lightNode)
- {
- super(assetManager, shadowMapSize, CAM_NUMBER);
- //_lights = new ArrayList<PointLight>();
- //Material mat = new Material(assetManager, "MatDefs/Shadow/PostShadowMS.j3md");
- //setPostShadowMaterial(mat);
- _lightNode = lightNode;
- //_playerCam = cam;
- init(shadowMapSize);
- }
- private void init(int shadowMapSize)
- {
- shadowCams = new Camera[CAM_NUMBER];
- for (int i = 0; i < CAM_NUMBER; i++) {
- shadowCams[i] = new Camera(shadowMapSize, shadowMapSize);
- }
- }
- @Override
- protected void updateShadowCams(Camera viewCam) {
- if (light == null)
- {
- throw new IllegalStateException("The light can't be null for a " + this.getClass().getName());
- }
- Quaternion q1 = null;
- Quaternion q2 = null;
- //bottom
- shadowCams[0].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Z.mult(-1f), Vector3f.UNIT_Y.mult(-1f));
- //q1 = shadowCams[0].getRotation();
- //q2 = new Quaternion();
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
- //shadowCams[0].setRotation(q2.mult(q1));
- //top
- shadowCams[1].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Z, Vector3f.UNIT_Y);
- //q1 = shadowCams[1].getRotation();
- //q2 = new Quaternion();
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
- //shadowCams[1].setRotation(q2.mult(q1));
- //forward
- shadowCams[2].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Y, Vector3f.UNIT_Z.mult(-1f));
- //q1 = shadowCams[2].getRotation();
- //q2 = new Quaternion();
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
- //shadowCams[2].setRotation(q2.mult(q1));
- //backward
- shadowCams[3].setAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z);
- //q1 = shadowCams[3].getRotation();
- //q2 = new Quaternion();
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
- //shadowCams[3].setRotation(q2.mult(q1));
- //left
- shadowCams[4].setAxes(Vector3f.UNIT_Z, Vector3f.UNIT_Y, Vector3f.UNIT_X.mult(-1f));
- //q1 = shadowCams[4].getRotation();
- //q2 = new Quaternion();
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
- //shadowCams[4].setRotation(q2.mult(q1));
- //right
- shadowCams[5].setAxes(Vector3f.UNIT_Z.mult(-1f), Vector3f.UNIT_Y, Vector3f.UNIT_X);
- //q1 = shadowCams[5].getRotation();
- //q2 = new Quaternion();
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
- //shadowCams[5].setRotation(q2.mult(q1));
- for (int i = 0; i < CAM_NUMBER; i++)
- {
- //q1 = shadowCams[i].getRotation();
- //q2 = new Quaternion();
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
- //Quaternion qq = q2.mult(q1);
- //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_X);
- //shadowCams[i].setRotation(qq.mult(q2));
- //shadowCams[i].setFrustumPerspective(90f, _playerCam.getFrustumRight() / _playerCam.getFrustumTop(),
- // 0.1f, light.getRadius()); //1f
- shadowCams[i].setFrustumPerspective(90f, 1.7f, 0.1f, light.getRadius()); //1f
- shadowCams[i].setLocation(light.getPosition());
- shadowCams[i].update();
- shadowCams[i].updateViewProjection();
- }
- }
- @Override
- protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList sceneOccluders, GeometryList sceneReceivers, GeometryList shadowMapOccluders) {
- ShadowUtil.getGeometriesInCamFrustum(sceneOccluders, shadowCams[shadowMapIndex], shadowMapOccluders);
- return shadowMapOccluders;
- }
- @Override
- GeometryList getReceivers(GeometryList sceneReceivers, GeometryList lightReceivers) {
- lightReceivers.clear();
- ShadowUtil.getGeometriesInLightRadius(sceneReceivers, shadowCams, lightReceivers);
- return lightReceivers;
- }
- @Override
- protected Camera getShadowCam(int shadowMapIndex) {
- return shadowCams[shadowMapIndex];
- }
- @Override
- protected void doDisplayFrustumDebug(int shadowMapIndex) {
- if (frustums == null) {
- frustums = new Geometry[CAM_NUMBER];
- Vector3f[] points = new Vector3f[8];
- for (int i = 0; i < 8; i++) {
- points[i] = new Vector3f();
- }
- for (int i = 0; i < CAM_NUMBER; i++) {
- ShadowUtil.updateFrustumPoints2(shadowCams[i], points);
- frustums[i] = createFrustum(points, i);
- }
- }
- if (frustums[shadowMapIndex].getParent() == null) {
- ((Node) viewPort.getScenes().get(0)).attachChild(frustums[shadowMapIndex]);
- }
- }
- @Override
- protected void setMaterialParameters(Material material)
- {
- material.setVector3("LightPos", light.getPosition());
- updatePostShadowMatParams(material);
- }
- protected void updatePostShadowMatParams(Material material)
- {
- Technique technique = material.getActiveTechnique();
- if (technique == null)
- return;
- LightList list = _lightNode.getLocalLightList(); // Node with lights.
- ArrayList<PointLight> arr = new ArrayList<PointLight>(list.size());
- Light l;
- float dist = 0;
- for (int i = 0; i < list.size(); i++)
- {
- l = list.get(i);
- if (l == light) continue;
- if (!(l instanceof PointLight)) continue;
- PointLight p = (PointLight)l;
- dist = p.getPosition().distance(light.getPosition());
- if (dist > p.getRadius() * 2) continue;
- arr.add(p);
- }
- if (arr.size() == 0) return;
- //Uniform lightPos = null;
- Vector3f pos = null;
- PointLight pl = null;
- try
- {
- material.getMaterialDef().addMaterialParam(VarType.Int, "LightCount", arr.size(), null);
- material.setInt("LightCount", arr.size());
- material.getMaterialDef().addMaterialParam(VarType.Float, "LightRadius", light.getRadius() * 1.450f, null); //
- material.setFloat("LightRadius", light.getRadius() * 1.350f);
- //material.getMaterialDef().addMaterialParam(VarType.Vector3Array, "LightsPositions", null, null);
- //material.setv
- //Shader shader = technique.getShader();
- //lightPos = shader.getUniform("g_LightPosition");
- //lightPos.setVector4Length(arr.size());
- int cnt = arr.size();
- if (cnt > 6)
- {
- // wybrac 6 najbliższych
- cnt = 6;
- float lx = light.getPosition().x;
- float ly = light.getPosition().z;
- _sortTmp = (lx * lx) + (ly * ly);
- Collections.sort(arr, this);
- }
- for (int i = 0; i < cnt; i++)
- {
- pl = arr.get(i);
- pos = pl.getPosition();
- float radius = pl.getInvRadius();
- //lightPos.setVector4InArray(pos.getX(), pos.getY(), pos.getZ(), radius, i);
- //TODO: zrobić statyczna(?) tabele nazw LightPositionX !
- Vector4f vpos = new Vector4f(pos.getX(), pos.getY(), pos.getZ(), radius);
- material.getMaterialDef().addMaterialParam(VarType.Vector4, "LightPosition" + i, vpos, null);
- material.setVector4("LightPosition" + i, vpos);
- }
- for (int i = cnt; i < 6; i++)
- {
- Vector4f vpos = new Vector4f(0, 0, 0, 0);
- material.getMaterialDef().addMaterialParam(VarType.Vector4, "LightPosition" + i, vpos, null);
- material.setVector4("LightPosition" + i, vpos);
- }
- //Uniform lightPos = shader.getUniform("g_LightPosition");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
- /**
- * gets the point light used to cast shadows with this processor
- *
- * @return the point light
- */
- public PointLight getLight() {
- return light;
- }
- /**
- * sets the light to use for casting shadows with this processor
- *
- * @param light the point light
- */
- public void setLight(PointLight light) {
- this.light = light;
- }
- @Override
- public void read(JmeImporter im) throws IOException {
- super.read(im);
- InputCapsule ic = (InputCapsule) im.getCapsule(this);
- light = (PointLight) ic.readSavable("light", null);
- init((int) shadowMapSize);
- }
- @Override
- public void write(JmeExporter ex) throws IOException {
- super.write(ex);
- OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
- oc.write(light, "light", null);
- }
- // Porównywacz odległości świateł
- @Override
- public int compare(PointLight o1, PointLight o2)
- {
- // _sortTmp wyliczone przed wywolaniem sortowania
- float ox = o1.getPosition().x;
- float oy = o1.getPosition().z;
- float b = (ox * ox) + (oy * oy);
- float d1 = (_sortTmp - b) * (_sortTmp + b); // a^2 - b^2
- ox = o2.getPosition().x;
- oy = o2.getPosition().z;
- b = (ox * ox) + (oy * oy);
- float d2 = (_sortTmp - b) * (_sortTmp + b); // a^2 - b^2
- if (d1 < d2) return -1;
- if (d1 > d2) return 1;
- return 0;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement