/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.jme3.post; import com.jme3.app.VRApplication; import com.jme3.asset.AssetManager; import com.jme3.material.Material; import com.jme3.post.Filter; import com.jme3.renderer.RenderManager; import com.jme3.renderer.Renderer; import com.jme3.renderer.ViewPort; import com.jme3.scene.Mesh; import com.jme3.scene.VertexBuffer; import com.jme3.system.jopenvr.DistortionCoordinates_t; import com.jme3.system.jopenvr.JOpenVRLibrary; import com.jme3.system.jopenvr.VR_IVRSystem_FnTable; import com.jme3.texture.FrameBuffer; /** * DO NOT USE * @author phr00t * @deprecated DO NOT USE */ @Deprecated public class OpenVRFilter extends Filter { private Mesh distortionMesh; private VRApplication application = null; /** * DO NOT USE * @param application the VR application. */ public OpenVRFilter(VRApplication application) { this.application = application; } /** * DO NOT USE * @return the distortion mesh. */ public Mesh getDistortionMesh() { return distortionMesh; } @Override protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) { material = new Material(manager, "Common/MatDefs/VR/OpenVR.j3md"); configureDistortionMesh(); } @Override protected Material getMaterial() { return material; } @Override protected void preFrame(float tpf) { super.preFrame(tpf); } @Override protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) { super.postFrame(renderManager, viewPort, prevFilterBuffer, sceneBuffer); } @Override protected void postFilter(Renderer r, FrameBuffer buffer) { super.postFilter(r, buffer); } /* function converted from: https://github.com/ValveSoftware/openvr/blob/master/samples/hellovr_opengl/hellovr_opengl_main.cpp#L1335 */ private void configureDistortionMesh() { float m_iLensGridSegmentCountH = 43, m_iLensGridSegmentCountV = 43; float w = 1f / m_iLensGridSegmentCountH - 1f; float h = 1f / m_iLensGridSegmentCountV - 1f; float u, v; distortionMesh = new Mesh(); float verts[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 3]; float texcoordR[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; float texcoordG[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; float texcoordB[] = new float[(int)(m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; int vertPos = 0, coordPos = 0; //left eye distortion verts float Xoffset = -1f; for( int y=0; y<m_iLensGridSegmentCountV; y++ ) { for( int x=0; x<m_iLensGridSegmentCountH; x++ ) { u = x*w; v = 1-y*h; verts[vertPos] = Xoffset+u; // x verts[vertPos+1] = -1+2*y*h; // y verts[vertPos+2] = 0f; // z vertPos += 3; DistortionCoordinates_t dc0 = new DistortionCoordinates_t(); ((VR_IVRSystem_FnTable)application.getVRHardware().getVRSystem()).ComputeDistortion.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, u, v, dc0); texcoordR[coordPos] = dc0.rfRed[0]; texcoordR[coordPos+1] = 1 - dc0.rfRed[1]; texcoordG[coordPos] = dc0.rfGreen[0]; texcoordG[coordPos+1] = 1 - dc0.rfGreen[1]; texcoordB[coordPos] = dc0.rfBlue[0]; texcoordB[coordPos+1] = 1 - dc0.rfBlue[1]; coordPos+=2; } } //right eye distortion verts Xoffset = 0; for( int y=0; y<m_iLensGridSegmentCountV; y++ ) { for( int x=0; x<m_iLensGridSegmentCountH; x++ ) { u = x*w; v = 1-y*h; verts[vertPos] = Xoffset+u; // x verts[vertPos+1] = -1+2*y*h; // y verts[vertPos+2] = 0f; // z vertPos += 3; DistortionCoordinates_t dc0 = new DistortionCoordinates_t(); ((VR_IVRSystem_FnTable)application.getVRHardware().getVRSystem()).ComputeDistortion.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, u, v, dc0); texcoordR[coordPos] = dc0.rfRed[0]; texcoordR[coordPos+1] = 1 - dc0.rfRed[1]; texcoordG[coordPos] = dc0.rfGreen[0]; texcoordG[coordPos+1] = 1 - dc0.rfGreen[1]; texcoordB[coordPos] = dc0.rfBlue[0]; texcoordB[coordPos+1] = 1 - dc0.rfBlue[1]; coordPos+=2; } } // have UV coordinates & positions, now to setup indices //std::vector<GLushort> vIndices; int[] indices = new int[(int)((m_iLensGridSegmentCountV - 1) * (m_iLensGridSegmentCountH - 1)) * 6]; int indexPos = 0; int a,b,c,d; int offset = 0; for( int y=0; y<m_iLensGridSegmentCountV-1; y++ ) { for( int x=0; x<m_iLensGridSegmentCountH-1; x++ ) { a = (int)(m_iLensGridSegmentCountH*y+x +offset); b = (int)(m_iLensGridSegmentCountH*y+x+1 +offset); c = (int)((y+1)*m_iLensGridSegmentCountH+x+1 +offset); d = (int)((y+1)*m_iLensGridSegmentCountH+x +offset); indices[indexPos] = a; indices[indexPos+1] = b; indices[indexPos+2] = c; indices[indexPos+3] = a; indices[indexPos+4] = c; indices[indexPos+5] = d; indexPos += 6; } } offset = (int)(m_iLensGridSegmentCountH * m_iLensGridSegmentCountV); for( int y=0; y<m_iLensGridSegmentCountV-1; y++ ) { for( int x=0; x<m_iLensGridSegmentCountH-1; x++ ) { a = (int)(m_iLensGridSegmentCountH*y+x +offset); b = (int)(m_iLensGridSegmentCountH*y+x+1 +offset); c = (int)((y+1)*m_iLensGridSegmentCountH+x+1 +offset); d = (int)((y+1)*m_iLensGridSegmentCountH+x +offset); indices[indexPos] = a; indices[indexPos+1] = b; indices[indexPos+2] = c; indices[indexPos+3] = a; indices[indexPos+4] = c; indices[indexPos+5] = d; indexPos += 6; } } // OK, create the mesh distortionMesh.setBuffer(VertexBuffer.Type.Position, 3, verts); distortionMesh.setBuffer(VertexBuffer.Type.Index, 1, indices); distortionMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, texcoordR); // TODO: are TexCoord2 & TexCoord3 even implemented in jME3? distortionMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, texcoordG); distortionMesh.setBuffer(VertexBuffer.Type.TexCoord3, 2, texcoordB); // TODO: make sure this distortion mesh is used instead of the fullscreen quad // when filter gets rendered.. might require changes to jME3 core..? } }