Explorar o código

Implemented project() and unProject in the new renderer, fixed entity input

Ivan Safrin %!s(int64=10) %!d(string=hai) anos
pai
achega
eab091498a

+ 3 - 1
Core/Contents/Include/PolyCamera.h

@@ -267,7 +267,7 @@ namespace Polycode {
              * @param matrix Custom projection matrix.
              * @see setProjectionMode
              */
-            void setProjectionMatrix(Matrix4 matrix);
+            void setCustomProjectionMatrix(Matrix4 matrix);
 			
             /**
              * Return's the camera's pixel viewport based on the last render pass.
@@ -311,6 +311,8 @@ namespace Polycode {
 
             void setUseGlobalFramebuffer(bool val);
             bool getUseGlobalFramebuffer() const;
+        
+            Vector3 projectRayFrom2DCoordinate(const Vector2 &coordinate, const Polycode::Rectangle &viewport);
 
 		protected:
 

+ 6 - 7
Core/Contents/Include/PolyEntity.h

@@ -36,6 +36,7 @@
 namespace Polycode {
 
 	class Renderer;
+    class Scene;
 
 	class _PolyExport MouseEventResult {
 		public:
@@ -829,13 +830,6 @@ namespace Polycode {
              * @return Pixel position of the entity on the screen.
              */
             Vector2 getScreenPosition(const Matrix4 &projectionMatrix, const Matrix4 &cameraMatrix, const Polycode::Rectangle &viewport);
-        
-            /**
-             * Returns the screen pixel position of the entity using the last projection matrix, camera matrix and viewport that were set in the renderer.
-             * @return Pixel position of the entity on the screen.
-             */
-			Vector2 getScreenPositionForMainCamera();
-
 
             /**
              * If set to true, will round the position of this entity to integral values. Use this if you need pixel-perfect positioning in 2D.
@@ -898,8 +892,13 @@ namespace Polycode {
         
             GPUDrawCall drawCall;
         
+            void setContainerScene(Scene *scene);
+    
+            Scene *getContainerScene();
+        
 		protected:
 
+            Scene *containerScene;
         
             AABB aabb;
             Vector3 bBox;

+ 18 - 3
Core/Contents/Include/PolyMatrix4.h

@@ -24,6 +24,7 @@ THE SOFTWARE.
 #include <string.h>
 #include "PolyGlobals.h"
 #include "PolyVector3.h"
+#include "PolyVector4.h"
 
 namespace Polycode {
 
@@ -129,17 +130,31 @@ namespace Polycode {
                            n*m[3][0], n*m[3][1], n*m[3][2], n*m[3][3]);
             }
         
-            inline Vector3 multVector( const Vector3 &v2 ) const
+            inline Vector3 multVector3( const Vector3 &v2 ) const
             {
                 return Vector3(v2.x*m[0][0] + v2.y*m[1][0] + v2.z*m[2][0] + m[3][0],
                                v2.x*m[0][1] + v2.y*m[1][1] + v2.z*m[2][1] + m[3][1],
                                v2.x*m[0][2] + v2.y*m[1][2] + v2.z*m[2][2] + m[3][2]);
             }
         
+            inline Vector4 multVector4( const Vector4 &v2 ) const
+            {
+                return Vector4(v2.x*m[0][0] + v2.y*m[1][0] + v2.z*m[2][0] + v2.w*m[3][0],
+                           v2.x*m[0][1] + v2.y*m[1][1] + v2.z*m[2][1] + v2.w*m[3][1],
+                           v2.x*m[0][2] + v2.y*m[1][2] + v2.z*m[2][2] + v2.w*m[3][2],
+                           v2.x*m[0][3] + v2.y*m[1][3] + v2.z*m[2][3] + v2.w*m[3][3]);
+            }
+        
 			inline Vector3 operator * ( const Vector3 &v2 ) const
 			{
-				return multVector(v2);
-			}			
+				return multVector3(v2);
+			}
+        
+        
+            inline Vector4 operator * ( const Vector4 &v2 ) const
+            {
+                return multVector4(v2);
+            }
 			
 			inline Number* operator [] ( int row ) { return m[row];}
 			inline const Number* operator [] ( int row ) const { return m[row];}

+ 5 - 0
Core/Contents/Include/PolyRenderer.h

@@ -145,6 +145,11 @@ namespace Polycode {
         void setAnisotropyAmount(Number amount);
         Number getAnisotropyAmount();
         
+        static Vector3 unProject(const Vector3 &position, const Matrix4 &modelMatrix, const Matrix4 &projectionMatrix, const Polycode::Rectangle &viewport);
+
+        static Vector3 project(const Vector3 &position, const Matrix4 &modelMatrix, const Matrix4 &projectionMatrix, const Polycode::Rectangle &viewport);
+        
+        
         void beginFrame();
         void endFrame();
         

+ 4 - 0
Core/Contents/Include/PolyVector4.h

@@ -22,6 +22,7 @@
 
 #pragma once
 #include "PolyGlobals.h"
+#include "PolyVector3.h"
 #include <math.h>
 
 //#ifdef _WINDOWS
@@ -44,6 +45,9 @@ namespace Polycode {
 			* @param w W coordinate.
 			*/					
 			Vector4(Number x,Number y,Number z, Number w);
+        
+        
+            Vector4(const Vector3 &v3);
 
 			/**
 			* Create from single value for all coordinates

+ 13 - 2
Core/Contents/Source/PolyCamera.cpp

@@ -473,7 +473,7 @@ void Camera::drawFilter(Texture *targetTexture, Number targetTextureWidth, Numbe
 }
 
 Matrix4 Camera::getProjectionMatrix() {
-	return projectionMatrix;
+	return createProjectionMatrix();
 }
 
 Polycode::Rectangle Camera::getViewport() {
@@ -496,7 +496,7 @@ void Camera::setProjectionMode(int mode) {
 	projectionMode = mode;
 }
 
-void Camera::setProjectionMatrix(Matrix4 matrix) {
+void Camera::setCustomProjectionMatrix(Matrix4 matrix) {
     projectionMatrix = matrix;
 }
 
@@ -508,6 +508,17 @@ void Camera::setOrthoMatrix(Matrix4 &matrix, Number xSize, Number ySize, Number
     }
 }
 
+Vector3 Camera::projectRayFrom2DCoordinate(const Vector2 &coordinate, const Polycode::Rectangle &viewport) {
+    Matrix4 camInverse = getConcatenatedMatrix().Inverse();
+    
+    Vector3 nearPlane = Renderer::unProject(Vector3(coordinate.x, coordinate.y, 0.0), camInverse, getProjectionMatrix(), viewport);
+    Vector3 farPlane = Renderer::unProject(Vector3(coordinate.x, coordinate.y, 1.0), camInverse, getProjectionMatrix(), viewport);
+    
+    Vector3 dirVec = (farPlane) - (nearPlane);
+    dirVec.Normalize();
+    return dirVec;
+}
+
 Matrix4 Camera::createProjectionMatrix() {
     
     Matrix4 retMatrix;

+ 16 - 12
Core/Contents/Source/PolyEntity.cpp

@@ -79,6 +79,7 @@ void Entity::initEntity() {
 	lastClickTicks = 0.0;
     rendererVis = true;
     layerID = 0;
+    containerScene = NULL;
 }
 
 Entity *Entity::getEntityById(String id, bool recursive) const {
@@ -459,17 +460,8 @@ Matrix4 Entity::getConcatenatedRollMatrix() const {
 
 Vector2 Entity::getScreenPosition(const Matrix4 &projectionMatrix, const Matrix4 &cameraMatrix, const Polycode::Rectangle &viewport) {
 	if(renderer){
-        // RENDERER_TODO
-		//return renderer->Project(cameraMatrix, projectionMatrix, viewport, getConcatenatedMatrix().getPosition());
-	} else {
-		return Vector2();
-	}
-}
-
-Vector2 Entity::getScreenPositionForMainCamera() {
-	if(renderer) {
-        // RENDERER_TODO
-		//return getScreenPosition(renderer->getProjectionMatrix(), renderer->getCameraMatrix(), renderer->getViewport());
+        Vector3 pos = Renderer::project(getConcatenatedMatrix().getPosition(), cameraMatrix, projectionMatrix, viewport);
+        return Vector2(pos.x, pos.y);
 	} else {
 		return Vector2();
 	}
@@ -480,7 +472,19 @@ void Entity::setDepthOnly(bool val) {
 }
 
 bool Entity::getDepthOnly() {
-    
+    return drawCall.options.depthOnly;
+}
+
+void Entity::setContainerScene(Scene *scene) {
+    this->containerScene = scene;
+}
+
+Scene *Entity::getContainerScene() {
+    if(parentEntity) {
+        return parentEntity->getContainerScene();
+    } else {
+        return containerScene;
+    }
 }
 
 void Entity::transformAndRender(GPUDrawBuffer *buffer) {

+ 46 - 0
Core/Contents/Source/PolyRenderer.cpp

@@ -25,6 +25,7 @@
 #include "PolyCoreServices.h"
 #include "PolyCore.h"
 #include "PolyTexture.h"
+#include "PolyVector4.h"
 
 using namespace Polycode;
 
@@ -366,4 +367,49 @@ void Renderer::destroyTexture(Texture *texture) {
 void Renderer::createRenderTextures(Texture **colorBuffer, Texture **depthBuffer, int width, int height, bool floatingPointBuffer) {
     
 }
+Vector3 Renderer::project(const Vector3 &position, const Matrix4 &modelMatrix, const Matrix4 &projectionMatrix, const Polycode::Rectangle &viewport) {
+    
+    Vector4 in(position);
+    Vector4 out = modelMatrix * in;
+    in = projectionMatrix * out;
+    
+    if (in.w == 0.0) return Vector3();
+    
+    in.x /= in.w;
+    in.y /= in.w;
+    in.z /= in.w;
+    
+    in.x = in.x * 0.5 + 0.5;
+    in.y = in.y * 0.5 + 0.5;
+    in.z = in.z * 0.5 + 0.5;
+    
+    in.x = in.x * (viewport.x + viewport.w) + viewport.x;
+    in.y = in.y * (viewport.y + viewport.h) + viewport.y;
+    
+    return Vector3(in.x, in.y, in.z);
+}
+
+Vector3 Renderer::unProject(const Vector3 &position, const Matrix4 &modelMatrix, const Matrix4 &projectionMatrix, const Polycode::Rectangle &viewport) {
 
+    Matrix4 finalMatrix = modelMatrix * projectionMatrix;
+    finalMatrix = finalMatrix.Inverse();
+    
+    Vector4 in(position);
+    
+    in.x = (in.x - viewport.x) / (viewport.x + viewport.w);
+    in.y = (in.y - viewport.y) / (viewport.y + viewport.h);
+    
+    in.x = in.x * 2.0 - 1.0;
+    in.y = in.y * 2.0 - 1.0;
+    in.z = in.z * 2.0 - 1.0;
+    
+    Vector4 out = finalMatrix * in;
+    
+    if(out.w == 0.0) return Vector3();
+    
+    out.x /= out.w;
+    out.y /= out.w;
+    out.z /= out.w;
+    
+    return Vector3(out.x, out.y, out.z);
+}

+ 2 - 4
Core/Contents/Source/PolyScene.cpp

@@ -49,6 +49,7 @@ Scene::Scene(int sceneType, bool virtualScene) : EventDispatcher() {
 
 void Scene::initScene(int sceneType, bool virtualScene) {
 
+    rootEntity.setContainerScene(this);
 	core = CoreServices::getInstance()->getCore();
 	this->sceneType = sceneType;
 	defaultCamera = new Camera(this);
@@ -325,8 +326,6 @@ void Scene::RenderDepthOnly(Camera *targetCamera) {
 
 Ray Scene::projectRayFromCameraAndViewportCoordinate(Camera *camera, Vector2 coordinate) {
 
-        // RENDERER_TODO
-    /*
 	Polycode::Rectangle viewport = camera->getViewport();
     
     if(remapMouse) {
@@ -334,7 +333,7 @@ Ray Scene::projectRayFromCameraAndViewportCoordinate(Camera *camera, Vector2 coo
         viewport.y = (core->getYRes() - (sceneMouseRect.y + sceneMouseRect.h)) * renderer->getBackingResolutionScaleY();
     }
     
-	Vector3 dir =  renderer->projectRayFrom2DCoordinate(coordinate.x *  renderer->getBackingResolutionScaleX(), coordinate.y  * renderer->getBackingResolutionScaleY(), camera->getConcatenatedMatrix(), camera->getProjectionMatrix(), viewport);
+    Vector3 dir =  camera->projectRayFrom2DCoordinate(Vector2(coordinate.x *  renderer->getBackingResolutionScaleX(), coordinate.y  * renderer->getBackingResolutionScaleY()), viewport);
 	Vector3 pos;
     
 	switch(sceneType) {
@@ -382,7 +381,6 @@ Ray Scene::projectRayFromCameraAndViewportCoordinate(Camera *camera, Vector2 coo
 
 
 	return Ray(pos, dir);
-*/     
 }
 
 

+ 7 - 0
Core/Contents/Source/PolyVector4.cpp

@@ -34,6 +34,13 @@ void Vector4::set(Number x, Number y, Number z, Number w) {
 	this->w = w;
 }
 
+Vector4::Vector4(const Vector3 &v3) {
+    x = v3.x;
+    y = v3.y;
+    z = v3.z;
+    w = 1.0;
+}
+
 Vector4::Vector4(Number x,Number y,Number z, Number w) {
 	set(x, y, z, w);
 }

+ 2 - 0
IDE/Contents/Source/PolycodeEditor.cpp

@@ -173,6 +173,8 @@ void PolycodeEditor::didAction(String actionName, PolycodeEditorActionData *befo
 
 void PolycodeEditor::Resize(int x, int y) {
 	editorSize = Vector2(x,y);
+    // RENDERER_TODO
+
 	Vector2 pos = getScreenPositionForMainCamera();
 	scissorBox.setRect(pos.x,pos.y, x, y);	
 }

+ 3 - 1
Modules/Contents/UI/Include/PolyUIElement.h

@@ -39,7 +39,9 @@ namespace Polycode {
 			virtual ~UIElement();
 			
 			virtual void Resize(Number width, Number height);
-						
+        
+            Vector2 getScreenPositionForMainCamera();
+        
 			bool hasFocus;
 			bool focusable;
 			

+ 17 - 0
Modules/Contents/UI/Source/PolyUIElement.cpp

@@ -28,6 +28,8 @@
 #include "PolyConfig.h"
 #include "PolyCoreInput.h"
 #include "PolyInputEvent.h"
+#include "PolyScene.h"
+#include "PolyCamera.h"
 
 using namespace Polycode;
 
@@ -457,6 +459,21 @@ UIElement::~UIElement() {
 	}
 }
 
+Vector2 UIElement::getScreenPositionForMainCamera() {
+    Scene *containerScene = getContainerScene();
+    Vector2 screenPos;
+    
+    if(containerScene) {
+        Camera *camera = containerScene->getActiveCamera();
+        if(camera) {
+            screenPos = getScreenPosition(camera->getProjectionMatrix(), camera->getConcatenatedMatrix().Inverse(), camera->getViewport());
+        }
+    }
+    screenPos.y = Services()->getCore()->getYRes() - screenPos.y;
+    
+    return screenPos;
+}
+
 void UIElement::focusPreviousChild() {
     
     int j = 0;