Code Sample - 3D Engine

From WakingApp SDKs
Jump to: navigation, search

This is a short sample of a scene ran by the engine.

All assets used in the sample are attached below.

First thing is creating a new class that inherits from WAScene and overriding the 2 existing methods Init and Update. Init will be called once at the start of the scene and Update will be called every frame.

ExampleScene.h

 1 #pragma once 
 2 
 3 class ExampleScene : public WAScene
 4 {
 5 	//called once at the start of the scene.
 6 	void Init() override;
 7 	
 8 	//called every frame.
 9 	void Update(const double deltaTime) override;
10 };

ExampleScene.cpp - Skybox Only

 1 #include "WAApi.h"
 2 #include "ExampleScene.h"
 3 
 4 void ExampleScene::Init()
 5 {
 6 	//sets the skybox/background of the scene.
 7 	SetSkybox("BolongaRadianceLL_0_1024x1024.png");
 8 }
 9 
10 void ExampleScene::Update(const double deltaTime)
11 {
12 }

ExampleScene.cpp - Complete

 1 #include "WAApi.h"
 2 #include "ExampleScene.h"
 3 
 4 WAObject* cameraAnchor;
 5 WAObject* cameraObject;
 6 WAObject* modelObject;
 7 WAObject* lightObject;
 8 
 9 void ExampleScene::Init()
10 {
11 	//sets the skybox/background of the scene.
12 	SetSkybox("BolongaRadianceLL_0_1024x1024.png");
13 
14 	//create an empty object for the camera anchor.
15 	cameraAnchor = CreateObject("CameraRotator");
16 
17 	//assign the camera object from the scene
18 	cameraObject = GetMainCamera()->GetConnectedObject();
19 
20 	//set the cameraAnchor as the parent of the camera and move the camera backwards on the Z axis.
21 	//this will allow rotation of the camera around the anchor by rotating the anchor.
22 	cameraObject->SetParent(cameraAnchor);
23 	cameraObject->GetComponent<WATransform>()->SetLocalPosition({0,0,-200});
24 	
25 	//create a light, set its rotation, color and intensity.
26 	lightObject = CreateObject("Light");
27 	lightObject->GetComponent<WATransform>()->SetLocalRotation(glm::vec3(90, 0, 0)); //light facing down
28 	WALight* light = lightObject->AddComponent<WALight>();
29 	light->SetColor(glm::vec4(1,1,1,1)); //light color is white
30 	light->SetIntensity(5);
31 	
32 	//create a model object then load it.
33 	modelObject = CreateObject("Model");
34 	modelObject->GetComponent<WATransform>()->SetLocalRotation({ 240,180,0 });
35 	WAModel* model = modelObject->AddComponent<WAModel>();
36 	model->LoadModel("watch/watch.gltf");
37 	
38 }
39 
40 void ExampleScene::Update(const double deltaTime)
41 {
42 	//allows mouse look around the object
43 	HandleCameraRotation();
44 }
45 
46 void ExampleScene::HandleCameraRotation() const
47 {
48 	//Implemented below
49 }

The method "HandleCameraRotation" will be used for handling user input for this scene, implementing drag and pinch inputs.

  • cameraAnchor is going to be the parent of the camera so when it's rotated the camera will circle around it on an axis.
  • cameraObject is going to be the camera object.
  • model and light are for the content in the scene.

The complete scene will look like this: Modelandskybox.png

In order to allow rotating around the model and zooming in and out the HandleCameraRotation method has to be implemented. (see below)

HandleCameraRotation()

This is an example of an input implementation using the API (drag and pinch)

 1 void ExampleScene::HandleCameraRotation() const
 2 {
 3 	static bool isTouchDown = false;
 4 	static bool isScaling = false;
 5 	static glm::vec2 initialTouchPos = { 0,0 };
 6 	static glm::vec2 touchDelta = { 0,0 };
 7 	static glm::vec2 lastTouchDelta = { 0,0 };
 8 	static glm::vec3 initialCameraRotation = { 0,0,0 };
 9 	static glm::vec3 currentCameraRotation = { 0,0,0 };
10     
11     	static float initialScaleDelta = 0;
12     	static float initialCameraDistance = 0;
13 	
14     	if (WAInput::TouchCount() == 1)
15 	{
16 		//if we were scaling reset everything
17         	if(isScaling)
18         	{
19 			isScaling = false;
20 			isTouchDown = false;
21 		}
22 
23 		if (!isTouchDown)
24 		{
25 			//touch started
26 			//reset touch position and camera rotation
27 			initialTouchPos = WAInput::GetTouch(0).location;
28 			initialCameraRotation = currentCameraRotation;
29 			isTouchDown = true;
30 		}
31 		else
32 		{
33 			//touch held/moved
34 			//calculate drag and rotate the camera accordingly
35 			touchDelta = initialTouchPos - WAInput::GetTouch(0).location;
36 			if (fabs(touchDelta.x - lastTouchDelta.x) > 1)
37 			{
38 				currentCameraRotation.y = initialCameraRotation.y;
39 				currentCameraRotation.y += touchDelta.x * 0.005f;
40 				cameraAnchor->GetComponent<WATransform>()->SetLocalRotation(currentCameraRotation);
41 			}
42 
43 			if(fabs(touchDelta.y - lastTouchDelta.y)>1)
44 			{
45 				currentCameraRotation.x = initialCameraRotation.x;
46 				currentCameraRotation.x += touchDelta.y * -0.005f;
47 				cameraAnchor->GetComponent<WATransform>()->SetLocalRotation(currentCameraRotation);
48 			}
49 
50 			lastTouchDelta = touchDelta;
51 		}
52 	}
53 	else if(WAInput::TouchCount() == 2) //2 fingers down means pinching
54 	{
55         	if(!isScaling)
56         	{
57 			//started scaling
58 			//reset the intinal scale data and the camera distance
59 			initialScaleDelta = glm::distance(WAInput::GetTouch(0).location,WAInput::GetTouch(1).location);
60 			initialCameraDistance = cameraObject->GetComponent<WATransform>()->GetLocalPosition().z;
61 			isScaling = true;
62 		}
63 		else
64 		{
65 			//pinch dragging, claculate the zoom
66 			float delta = glm::distance(WAInput::GetTouch(0).location,WAInput::GetTouch(1).location);
67 			float newCameraDistance = (initialScaleDelta/delta);
68 			cameraObject->GetComponent<WATransform>()->SetLocalPosition({0,0,initialCameraDistance*newCameraDistance});
69 		}
70         
71 	}
72 	else if(WAInput::GetMouseScroll() != 0) //for pc testing, mouse scroll wheel alternative for pinch
73 	{
74 		initialCameraDistance = cameraObject->GetComponent<WATransform>()->GetLocalPosition().z;
75 		cameraObject->GetComponent<WATransform>()->SetLocalPosition({ 0,0,initialCameraDistance + WAInput::GetMouseScroll()*15 });
76 	}
77 	else //no fingers on screen and no mouse wheel
78 	{
79 		if(isScaling)
80 		{
81 			isScaling = false;
82 		}
83 
84 		if (isTouchDown)
85 		{
86 			//touch up, set everything to false
87 			isTouchDown = false;
88 			touchDelta = { 0,0 };
89 			lastTouchDelta = { 0,0 };
90 		}
91 	}
92 }

Running the scene is pretty simple. Once it's finished use the LoadScene method of the engine's instance.

	engine.LoadScene<ExampleScene>();

Attached, the asset files used in this sample.

Media:Assets.zip