فهرست منبع

Updated PBS example so viewed object can be rotated

BearishSun 8 سال پیش
والد
کامیت
bd2fb603be

+ 2 - 0
Source/ExamplePhysicallyBasedShading/CMakeSources.cmake

@@ -1,9 +1,11 @@
 set(BS_EXAMPLEPHYSICALLYBASEDSHADING_INC_NOFILTER
 	"Include/CameraFlyer.h"
+	"Include/ObjectRotator.h"
 )
 
 set(BS_EXAMPLEPHYSICALLYBASEDSHADING_SRC_NOFILTER
 	"Source/CameraFlyer.cpp"
+	"Source/ObjectRotator.cpp"
 	"Source/Main.cpp"
 )
 

+ 32 - 0
Source/ExamplePhysicallyBasedShading/Include/ObjectRotator.h

@@ -0,0 +1,32 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsComponent.h"
+#include "BsMath.h"
+#include "BsVirtualInput.h"
+
+namespace bs
+{
+	/** Component that controls rotation of its scene object. */
+	class ObjectRotator : public Component
+	{
+	public:
+		ObjectRotator(const HSceneObject& parent);
+
+		/** Triggered once per frame. Allows the component to handle input and move. */
+		virtual void update();
+
+	private:
+		Degree mPitch; /**< Current pitch rotation of the object (up or down). */
+		Degree mYaw; /**< Current yar rotation of the object (left or right). */
+		bool mLastButtonState; /**< Determines was the user rotating the object last frame. */
+
+		VirtualButton mRotateObj; /**< Key that allows object to be rotated while held. */
+		VirtualAxis mVerticalAxis; /**< Input device axis used for controlling object's pitch rotation (up/down). */
+		VirtualAxis mHorizontalAxis; /**< Input device axis used for controlling object's yaw rotation (left/right). */
+
+		static const float ROTATION_SPEED; /**< Determines speed for rotation, in degrees per second. */
+	};
+}

+ 5 - 0
Source/ExamplePhysicallyBasedShading/Source/Main.cpp

@@ -24,6 +24,7 @@
 
 // Example includes
 #include "CameraFlyer.h"
+#include "ObjectRotator.h"
 
 namespace bs
 {
@@ -277,6 +278,9 @@ namespace bs
 		renderable->setMesh(mesh);
 		renderable->setMaterial(material);
 
+		// Add a rotator component so we can rotate the object during runtime
+		pistolSO->addComponent<ObjectRotator>();
+
         /************************************************************************/
         /* 									LIGHT                       		*/
         /************************************************************************/
@@ -364,6 +368,7 @@ namespace bs
 		inputConfig->registerButton("Left", BC_LEFT);
 		inputConfig->registerButton("Right", BC_RIGHT);
 		inputConfig->registerButton("FastMove", BC_LSHIFT);
+		inputConfig->registerButton("RotateObj", BC_MOUSE_LEFT);
 		inputConfig->registerButton("RotateCam", BC_MOUSE_RIGHT);
 
 		// Camera controls for axes (analog input, e.g. mouse or gamepad thumbstick)

+ 77 - 0
Source/ExamplePhysicallyBasedShading/Source/ObjectRotator.cpp

@@ -0,0 +1,77 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "ObjectRotator.h"
+#include "BsVector3.h"
+#include "BsTime.h"
+#include "BsMath.h"
+#include "BsSceneObject.h"
+#include "BsCursor.h"
+
+namespace bs
+{
+	const float ObjectRotator::ROTATION_SPEED = 360.0f; // Degrees/second
+
+	/** Wraps an angle so it always stays in [0, 360) range. */
+	Degree wrapAngle2(Degree angle)
+	{
+		if (angle.valueDegrees() < -360.0f)
+			angle += Degree(360.0f);
+
+		if (angle.valueDegrees() > 360.0f)
+			angle -= Degree(360.0f);
+
+		return angle;
+	}
+
+	ObjectRotator::ObjectRotator(const HSceneObject& parent)
+		:Component(parent), mPitch(0.0f), mYaw(0.0f), mLastButtonState(false)
+	{
+		// Set a name for the component, so we can find it later if needed
+		setName("ObjectRotator");
+
+		// Get handles for key bindings. Actual keys attached to these bindings will be registered during app start-up.
+		mRotateObj = VirtualButton("RotateObj");
+		mHorizontalAxis = VirtualAxis("Horizontal");
+		mVerticalAxis = VirtualAxis("Vertical");
+	}
+
+	void ObjectRotator::update()
+	{
+		// Check if any movement or rotation keys are being held
+		bool isRotating = gVirtualInput().isButtonHeld(mRotateObj);
+
+		// If switch to or from rotation mode, hide or show the cursor
+		if (isRotating != mLastButtonState)
+		{
+			if (isRotating)
+				Cursor::instance().hide();
+			else
+				Cursor::instance().show();
+
+			mLastButtonState = isRotating;
+		}
+
+		// If we're rotating, apply new pitch/yaw rotation values depending on the amount of rotation from the
+		// vertical/horizontal axes.
+		float frameDelta = gTime().getFrameDelta();
+		if (isRotating)
+		{
+			mYaw -= Degree(gVirtualInput().getAxisValue(mHorizontalAxis) * ROTATION_SPEED * frameDelta);
+			mPitch -= Degree(gVirtualInput().getAxisValue(mVerticalAxis) * ROTATION_SPEED * frameDelta);
+
+			mYaw = wrapAngle2(mYaw);
+			mPitch = wrapAngle2(mPitch);
+
+			Quaternion yRot;
+			yRot.fromAxisAngle(Vector3::UNIT_Y, Radian(mYaw));
+
+			Quaternion xRot;
+			xRot.fromAxisAngle(Vector3::UNIT_X, Radian(mPitch));
+
+			Quaternion camRot = yRot * xRot;
+			camRot.normalize();
+
+			SO()->setRotation(camRot);
+		}
+	}
+}