Tutorial_Obstacles.cpp

Tutorial_Obstacles.cpp
/*
* Copyright 2016 Autodesk, Inc. All rights reserved.
* Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
* or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
*/
#include "common/oneworldenv.h"
#include "labengine/base/kaimfileopener.h"
namespace
{
#define KT_TEST_ENV_CLASS OneWorldEnv
KT_TEST_ENV {}
// This tutorial illustrates how to create, update, and remove Cylinder and Box obstacles.
KT_TUTORIAL // Create and update CylinderObstacle
{
KT_LOG_TITLE_BEGIN("TUTORIAL - Create and update CylinderObstacle");
KT_ASSERT(KT_ENV.AddNavData("generated/plane200x200_80ktri/plane200x200_80ktri.NavData") != nullptr);
KT_ENV.StartVisualDebugUsingLocalFile("CylinderObstacle.VisualDebug"); // Load this file in the NavigationLab to view the result of this tutorial
Kaim::World* navWorld = KT_ENV.GetNavWorld();
Kaim::Ptr<Kaim::CylinderObstacle> cylinderObstacle = *KY_NEW Kaim::CylinderObstacle;
Kaim::CylinderObstacleInitConfig cylinderObstacleInitConfig;
cylinderObstacleInitConfig.m_world = KT_ENV.GetNavWorld(); // Kaim::World is mandatory
cylinderObstacleInitConfig.m_startPosition = Kaim::Vec3f(1.f, 0.f, 0.f);
cylinderObstacleInitConfig.m_height = 2.f;
cylinderObstacleInitConfig.m_radius = 1.f;
cylinderObstacle->Init(cylinderObstacleInitConfig);
for (KyUInt32 gameFrame = 0; gameFrame < 10; ++gameFrame)
{
// Obstacles can be added or removed during the course of a game;
// they are only updated when they have effectively changed.
switch (gameFrame)
{
case 0:
cylinderObstacle->AddToWorld(); // add your obstacle to the world
case 1:
case 2:
case 3:
case 7:
{
// Consider that the obstacle moves during these frames.
cylinderObstacle->SetPosition(cylinderObstacle->GetPosition() + cylinderObstacle->GetVelocity());
cylinderObstacle->SetVelocity(Kaim::Vec3f::UnitX());
break;
}
case 4:
cylinderObstacle->RemoveFromWorld(); // Remove the obstacle from the world.
break;
case 6:
cylinderObstacle->AddToWorld(); // (Re)Add the obstacle to the world.
break;
case 8:
{
cylinderObstacle->SetPosition(cylinderObstacle->GetPosition());
cylinderObstacle->SetVelocity(Kaim::Vec3f::Zero());
break;
}
default:
break;
}
navWorld->Update();
}
cylinderObstacle = nullptr;
KT_ENV.CleanUpWorld();
}
KT_TUTORIAL // Create and Update BoxObstacle
{
KT_LOG_TITLE_BEGIN("TUTORIAL - Create and Update BoxObstacle");
KT_ASSERT(KT_ENV.AddNavData("generated/plane200x200_80ktri/plane200x200_80ktri.NavData") != nullptr);
KT_ENV.StartVisualDebugUsingLocalFile("BoxObstacle.VisualDebug"); // Load this file in the NavigationLav to watch the result of this tutorial
Kaim::World* navWorld = KT_ENV.GetNavWorld();
// Create and initialize the BoxObstacle.
Kaim::Ptr<Kaim::BoxObstacle> boxObstacle = *KY_NEW Kaim::BoxObstacle;
Kaim::BoxObstacleInitConfig boxObstacleInitConfig;
boxObstacleInitConfig.m_world = KT_ENV.GetNavWorld(); // Kaim::World is mandatory
boxObstacleInitConfig.m_startPosition = Kaim::Vec3f(1.f, 0.f, 0.f);
boxObstacleInitConfig.m_rotationMode = Kaim::BoxObstacleRotation_Free; // the expected rotation model
boxObstacleInitConfig.m_localHalfExtents = Kaim::Vec3f(1.f, 1.f, 1.f); // this example is a box of one cubic meter
boxObstacle->Init(boxObstacleInitConfig);
boxObstacle->AddToWorld(); // add your obstacle to the world
for (KyUInt32 gameFrame = 0; gameFrame < 10; ++gameFrame)
{
// BoxObstacles are similar to CylinderObstacle in terms of removal from and addition to the world;
// the BoxObstacle update config is, however, different from the CylinderObstacle update config:
// a Kaim::Transofrm gives the position and orientation of the Kaim::BoxObstacle, and
// linear and angular velocities must be update as well.
const Kaim::Vec3f boxCenterRelativePosition = boxObstacle->GetTransform().Rotate(boxObstacle->GetLocalCenter());
Kaim::Vec3f boxCenterOnNavMesh = boxObstacle->GetTransform().T + boxCenterRelativePosition;
boxCenterOnNavMesh += Kaim::Vec3f::UnitX();
Kaim::Transform transform;
transform.T = boxCenterOnNavMesh;
boxObstacle->SetTransform(transform);
navWorld->Update();
}
boxObstacle = nullptr;
KT_ENV.CleanUpWorld();
}
KT_TUTORIAL // Create and Update BoxObstacle in a Y-up client world
{
KT_LOG_TITLE_BEGIN("TUTORIAL - Create and Update BoxObstacle");
KT_ASSERT(KT_ENV.AddNavData("generated/village_with_building_100m_yUP/village_with_building_100m_yUP.NavData") != nullptr);
KT_ENV.StartVisualDebugUsingLocalFile("BoxObstacle_Yup.VisualDebug"); // Load this file in the NavigationLav to watch the result of this tutorial
Kaim::World* navWorld = KT_ENV.GetNavWorld();
// Setup a CoordSystem to ease the game world <=> Navigation world conversions
Kaim::CoordSystem coordSystem;
KyFloat32 oneMeterInClientUnits = 100.0f;
coordSystem.Setup(oneMeterInClientUnits, clientAxisForX, clientAxisForY, clientAxisForZ);
// Define box parameters in client coordinate system
Kaim::Vec3f boxClientHalfExtents(200.0f, 50.0f, 100.0f);
Kaim::Vec3f boxClientAngularVelocity(0.0f, Kaim::KY_PI, 0.0f);
Kaim::Transform boxClientTransform;
boxClientTransform.R.SetRotation(Kaim::Vec3f(1.0f, 0.0f, 0.0f), Kaim::KY_PI / 3.0f); // initial rotation is 60 degrees counterclockwise around Navigation X axis (client X too)
boxClientTransform.T.Set(3000.0f, -50.0f, 3000.0f); // 1 meter is client 100 units
// Create and initialize the BoxObstacle.
Kaim::Ptr<Kaim::BoxObstacle> boxObstacle = *KY_NEW Kaim::BoxObstacle;
Kaim::BoxObstacleInitConfig boxObstacleInitConfig;
boxObstacleInitConfig.m_world = KT_ENV.GetNavWorld(); // Kaim::World is mandatory
boxObstacleInitConfig.m_rotationMode = Kaim::BoxObstacleRotation_Yaw;
coordSystem.ClientToNavigation_Pos(boxClientTransform.T, boxObstacleInitConfig.m_startPosition);
coordSystem.ClientToNavigation_Extents(boxClientHalfExtents, boxObstacleInitConfig.m_localHalfExtents);
boxObstacle->Init(boxObstacleInitConfig);
boxObstacle->AddToWorld(); // add your obstacle to the world
// This matrix express the frame rotation to apply to the box in client coordinate system.
// This is a yaw-only rotation (i.e. around client Y axis) with a angular speed of Pi / 4 rad per second
// at 60 frame per seconds.
const Kaim::Matrix3x3f clientRotationMatrix(Kaim::Vec3f(0.0f, 1.0f, 0.0f), 0.004f * Kaim::KY_PI);
for (KyUInt32 gameFrame = 0; gameFrame < 100; ++gameFrame)
{
// Update client box. This should be done by your physics or equivalent component
// in your own simulation.
boxClientTransform.R = clientRotationMatrix.Transform(boxClientTransform.R);
// Update Navigation box accordingly
Kaim::Transform transform;
Kaim::Vec3f angularVelocity;
coordSystem.ClientToNavigation_Transform(boxClientTransform, transform);
coordSystem.ClientToNavigation_AngularVelocity(boxClientAngularVelocity, angularVelocity);
boxObstacle->SetTransform(transform);
boxObstacle->SetAngularVelocity(angularVelocity);
navWorld->Update();
}
boxObstacle = nullptr;
KT_ENV.CleanUpWorld();
}
}