Advertisement
Guest User

MultiPointLightShadowRenderer

a guest
Oct 30th, 2014
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.43 KB | None | 0 0
  1. package com.dungeongame.gameclient.scene3d;
  2.  
  3. /*
  4. * Copyright (c) 2009-2012 jMonkeyEngine
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * * Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  19. * may be used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  24. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  25. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  26. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  28. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  29. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34.  
  35. import com.jme3.asset.AssetManager;
  36. import com.jme3.export.InputCapsule;
  37. import com.jme3.export.JmeExporter;
  38. import com.jme3.export.JmeImporter;
  39. import com.jme3.export.OutputCapsule;
  40. import com.jme3.light.Light;
  41. import com.jme3.light.LightList;
  42. import com.jme3.light.PointLight;
  43. import com.jme3.material.MatParam;
  44. import com.jme3.material.Material;
  45. import com.jme3.material.Technique;
  46. import com.jme3.math.FastMath;
  47. import com.jme3.math.Quaternion;
  48. import com.jme3.math.Vector2f;
  49. import com.jme3.math.Vector3f;
  50. import com.jme3.math.Vector4f;
  51. import com.jme3.renderer.Camera;
  52. import com.jme3.renderer.Caps;
  53. import com.jme3.renderer.RenderManager;
  54. import com.jme3.renderer.ViewPort;
  55. import com.jme3.renderer.queue.GeometryList;
  56. import com.jme3.renderer.queue.RenderQueue.ShadowMode;
  57. import com.jme3.scene.Geometry;
  58. import com.jme3.scene.Node;
  59. import com.jme3.shader.Shader;
  60. import com.jme3.shader.Uniform;
  61. import com.jme3.shader.VarType;
  62. import com.jme3.shadow.AbstractShadowRenderer;
  63. import com.jme3.shadow.CompareMode;
  64. import com.jme3.shadow.PointLightShadowRenderer;
  65. import com.jme3.shadow.ShadowUtil;
  66. import com.jme3.texture.FrameBuffer;
  67.  
  68. import java.io.IOException;
  69. import java.util.ArrayList;
  70. import java.util.Arrays;
  71. import java.util.Collections;
  72. import java.util.Comparator;
  73.  
  74.  
  75. public class MultiPointLightShadowRenderer extends MyAbstractShadowRenderer
  76. implements Comparator<PointLight>
  77. {
  78.  
  79. public static final int CAM_NUMBER = 6;
  80. protected PointLight light;
  81. protected Camera[] shadowCams;
  82. private Geometry[] frustums = null;
  83. private float _sortTmp;
  84.  
  85. private Node _lightNode;
  86. //private Camera _playerCam;
  87.  
  88. /**
  89. * Used for serialization use
  90. * PointLightShadowRenderer"PointLightShadowRenderer(AssetManager
  91. * assetManager, int shadowMapSize)
  92. */
  93. public MultiPointLightShadowRenderer()
  94. {
  95. super();
  96. //_lights = new ArrayList<PointLight>();
  97. }
  98.  
  99. /**
  100. * Creates a PointLightShadowRenderer
  101. *
  102. * @param assetManager the application asset manager
  103. * @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
  104. * etc...)
  105. */
  106. public MultiPointLightShadowRenderer(AssetManager assetManager, int shadowMapSize, Node lightNode)
  107. {
  108. super(assetManager, shadowMapSize, CAM_NUMBER);
  109.  
  110. //_lights = new ArrayList<PointLight>();
  111. //Material mat = new Material(assetManager, "MatDefs/Shadow/PostShadowMS.j3md");
  112. //setPostShadowMaterial(mat);
  113.  
  114. _lightNode = lightNode;
  115. //_playerCam = cam;
  116.  
  117. init(shadowMapSize);
  118.  
  119.  
  120.  
  121. }
  122.  
  123. private void init(int shadowMapSize)
  124. {
  125. shadowCams = new Camera[CAM_NUMBER];
  126. for (int i = 0; i < CAM_NUMBER; i++) {
  127. shadowCams[i] = new Camera(shadowMapSize, shadowMapSize);
  128. }
  129. }
  130.  
  131. @Override
  132. protected void updateShadowCams(Camera viewCam) {
  133.  
  134. if (light == null)
  135. {
  136. throw new IllegalStateException("The light can't be null for a " + this.getClass().getName());
  137. }
  138.  
  139. Quaternion q1 = null;
  140. Quaternion q2 = null;
  141.  
  142. //bottom
  143. shadowCams[0].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Z.mult(-1f), Vector3f.UNIT_Y.mult(-1f));
  144. //q1 = shadowCams[0].getRotation();
  145. //q2 = new Quaternion();
  146. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
  147. //shadowCams[0].setRotation(q2.mult(q1));
  148.  
  149. //top
  150. shadowCams[1].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Z, Vector3f.UNIT_Y);
  151. //q1 = shadowCams[1].getRotation();
  152. //q2 = new Quaternion();
  153. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
  154. //shadowCams[1].setRotation(q2.mult(q1));
  155.  
  156. //forward
  157. shadowCams[2].setAxes(Vector3f.UNIT_X.mult(-1f), Vector3f.UNIT_Y, Vector3f.UNIT_Z.mult(-1f));
  158. //q1 = shadowCams[2].getRotation();
  159. //q2 = new Quaternion();
  160. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
  161. //shadowCams[2].setRotation(q2.mult(q1));
  162.  
  163. //backward
  164. shadowCams[3].setAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z);
  165. //q1 = shadowCams[3].getRotation();
  166. //q2 = new Quaternion();
  167. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
  168. //shadowCams[3].setRotation(q2.mult(q1));
  169.  
  170. //left
  171. shadowCams[4].setAxes(Vector3f.UNIT_Z, Vector3f.UNIT_Y, Vector3f.UNIT_X.mult(-1f));
  172. //q1 = shadowCams[4].getRotation();
  173. //q2 = new Quaternion();
  174. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
  175. //shadowCams[4].setRotation(q2.mult(q1));
  176.  
  177. //right
  178. shadowCams[5].setAxes(Vector3f.UNIT_Z.mult(-1f), Vector3f.UNIT_Y, Vector3f.UNIT_X);
  179. //q1 = shadowCams[5].getRotation();
  180. //q2 = new Quaternion();
  181. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
  182. //shadowCams[5].setRotation(q2.mult(q1));
  183.  
  184. for (int i = 0; i < CAM_NUMBER; i++)
  185. {
  186. //q1 = shadowCams[i].getRotation();
  187. //q2 = new Quaternion();
  188. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y);
  189. //Quaternion qq = q2.mult(q1);
  190. //q2.fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_X);
  191. //shadowCams[i].setRotation(qq.mult(q2));
  192.  
  193. //shadowCams[i].setFrustumPerspective(90f, _playerCam.getFrustumRight() / _playerCam.getFrustumTop(),
  194. // 0.1f, light.getRadius()); //1f
  195. shadowCams[i].setFrustumPerspective(90f, 1.7f, 0.1f, light.getRadius()); //1f
  196. shadowCams[i].setLocation(light.getPosition());
  197. shadowCams[i].update();
  198. shadowCams[i].updateViewProjection();
  199. }
  200.  
  201. }
  202.  
  203. @Override
  204. protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList sceneOccluders, GeometryList sceneReceivers, GeometryList shadowMapOccluders) {
  205. ShadowUtil.getGeometriesInCamFrustum(sceneOccluders, shadowCams[shadowMapIndex], shadowMapOccluders);
  206. return shadowMapOccluders;
  207. }
  208.  
  209. @Override
  210. GeometryList getReceivers(GeometryList sceneReceivers, GeometryList lightReceivers) {
  211. lightReceivers.clear();
  212. ShadowUtil.getGeometriesInLightRadius(sceneReceivers, shadowCams, lightReceivers);
  213. return lightReceivers;
  214. }
  215.  
  216. @Override
  217. protected Camera getShadowCam(int shadowMapIndex) {
  218. return shadowCams[shadowMapIndex];
  219. }
  220.  
  221. @Override
  222. protected void doDisplayFrustumDebug(int shadowMapIndex) {
  223. if (frustums == null) {
  224. frustums = new Geometry[CAM_NUMBER];
  225. Vector3f[] points = new Vector3f[8];
  226. for (int i = 0; i < 8; i++) {
  227. points[i] = new Vector3f();
  228. }
  229. for (int i = 0; i < CAM_NUMBER; i++) {
  230. ShadowUtil.updateFrustumPoints2(shadowCams[i], points);
  231. frustums[i] = createFrustum(points, i);
  232. }
  233. }
  234. if (frustums[shadowMapIndex].getParent() == null) {
  235. ((Node) viewPort.getScenes().get(0)).attachChild(frustums[shadowMapIndex]);
  236. }
  237. }
  238.  
  239. @Override
  240. protected void setMaterialParameters(Material material)
  241. {
  242. material.setVector3("LightPos", light.getPosition());
  243.  
  244. updatePostShadowMatParams(material);
  245. }
  246.  
  247. protected void updatePostShadowMatParams(Material material)
  248. {
  249. Technique technique = material.getActiveTechnique();
  250. if (technique == null)
  251. return;
  252.  
  253. LightList list = _lightNode.getLocalLightList(); // Node with lights.
  254. ArrayList<PointLight> arr = new ArrayList<PointLight>(list.size());
  255.  
  256. Light l;
  257. float dist = 0;
  258.  
  259. for (int i = 0; i < list.size(); i++)
  260. {
  261. l = list.get(i);
  262. if (l == light) continue;
  263. if (!(l instanceof PointLight)) continue;
  264.  
  265. PointLight p = (PointLight)l;
  266.  
  267. dist = p.getPosition().distance(light.getPosition());
  268. if (dist > p.getRadius() * 2) continue;
  269.  
  270. arr.add(p);
  271. }
  272.  
  273. if (arr.size() == 0) return;
  274.  
  275. //Uniform lightPos = null;
  276. Vector3f pos = null;
  277. PointLight pl = null;
  278.  
  279. try
  280. {
  281. material.getMaterialDef().addMaterialParam(VarType.Int, "LightCount", arr.size(), null);
  282. material.setInt("LightCount", arr.size());
  283. material.getMaterialDef().addMaterialParam(VarType.Float, "LightRadius", light.getRadius() * 1.450f, null); //
  284. material.setFloat("LightRadius", light.getRadius() * 1.350f);
  285. //material.getMaterialDef().addMaterialParam(VarType.Vector3Array, "LightsPositions", null, null);
  286.  
  287. //material.setv
  288. //Shader shader = technique.getShader();
  289.  
  290. //lightPos = shader.getUniform("g_LightPosition");
  291. //lightPos.setVector4Length(arr.size());
  292.  
  293. int cnt = arr.size();
  294. if (cnt > 6)
  295. {
  296. // wybrac 6 najbliższych
  297. cnt = 6;
  298.  
  299. float lx = light.getPosition().x;
  300. float ly = light.getPosition().z;
  301. _sortTmp = (lx * lx) + (ly * ly);
  302.  
  303. Collections.sort(arr, this);
  304. }
  305.  
  306. for (int i = 0; i < cnt; i++)
  307. {
  308. pl = arr.get(i);
  309.  
  310. pos = pl.getPosition();
  311. float radius = pl.getInvRadius();
  312. //lightPos.setVector4InArray(pos.getX(), pos.getY(), pos.getZ(), radius, i);
  313.  
  314. //TODO: zrobić statyczna(?) tabele nazw LightPositionX !
  315. Vector4f vpos = new Vector4f(pos.getX(), pos.getY(), pos.getZ(), radius);
  316. material.getMaterialDef().addMaterialParam(VarType.Vector4, "LightPosition" + i, vpos, null);
  317. material.setVector4("LightPosition" + i, vpos);
  318. }
  319. for (int i = cnt; i < 6; i++)
  320. {
  321. Vector4f vpos = new Vector4f(0, 0, 0, 0);
  322. material.getMaterialDef().addMaterialParam(VarType.Vector4, "LightPosition" + i, vpos, null);
  323. material.setVector4("LightPosition" + i, vpos);
  324. }
  325.  
  326. //Uniform lightPos = shader.getUniform("g_LightPosition");
  327.  
  328. }
  329. catch (Exception e)
  330. {
  331. e.printStackTrace();
  332. }
  333. }
  334.  
  335. /**
  336. * gets the point light used to cast shadows with this processor
  337. *
  338. * @return the point light
  339. */
  340. public PointLight getLight() {
  341. return light;
  342. }
  343.  
  344. /**
  345. * sets the light to use for casting shadows with this processor
  346. *
  347. * @param light the point light
  348. */
  349. public void setLight(PointLight light) {
  350. this.light = light;
  351. }
  352.  
  353. @Override
  354. public void read(JmeImporter im) throws IOException {
  355. super.read(im);
  356. InputCapsule ic = (InputCapsule) im.getCapsule(this);
  357. light = (PointLight) ic.readSavable("light", null);
  358. init((int) shadowMapSize);
  359. }
  360.  
  361. @Override
  362. public void write(JmeExporter ex) throws IOException {
  363. super.write(ex);
  364. OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
  365. oc.write(light, "light", null);
  366. }
  367.  
  368. // Porównywacz odległości świateł
  369. @Override
  370. public int compare(PointLight o1, PointLight o2)
  371. {
  372. // _sortTmp wyliczone przed wywolaniem sortowania
  373.  
  374. float ox = o1.getPosition().x;
  375. float oy = o1.getPosition().z;
  376. float b = (ox * ox) + (oy * oy);
  377. float d1 = (_sortTmp - b) * (_sortTmp + b); // a^2 - b^2
  378.  
  379. ox = o2.getPosition().x;
  380. oy = o2.getPosition().z;
  381. b = (ox * ox) + (oy * oy);
  382. float d2 = (_sortTmp - b) * (_sortTmp + b); // a^2 - b^2
  383.  
  384. if (d1 < d2) return -1;
  385. if (d1 > d2) return 1;
  386.  
  387. return 0;
  388. }
  389. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement