// Copyright (C) 2014, Panagiotis Christopoulos Charitos. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE #include "anki/scene/PlayerNode.h" #include "anki/scene/SceneGraph.h" #include "anki/scene/MoveComponent.h" #include "anki/scene/PlayerControllerComponent.h" #include "anki/physics/PhysicsPlayerController.h" #include "anki/physics/PhysicsWorld.h" #include "anki/input/Input.h" namespace anki { //============================================================================== // PlayerNodeFeedbackComponent = //============================================================================== /// Feedback component. class PlayerNodeFeedbackComponent final: public SceneComponent { public: PlayerNodeFeedbackComponent(SceneNode* node) : SceneComponent(SceneComponent::Type::NONE, node) {} Error update(SceneNode& node, F32, F32, Bool& updated) override { updated = false; PlayerControllerComponent& playerc = node.getComponent(); const Input& in = node.getSceneGraph().getInput(); const F32 ang = toRad(7.0); F32 y = in.getMousePosition().y(); F32 x = in.getMousePosition().x(); if(playerc.getTimestamp() == node.getGlobalTimestamp() || y != 0.0 || x != 0.0) { MoveComponent& move = node.getComponent(); // Set origin Vec4 origin = playerc.getTransform().getOrigin(); origin.y() += 1.9; // Set rotation Mat3x4 rot(Euler(ang * y * -11.25, ang * x * -20.0, 0.0)); rot = move.getLocalRotation().combineTransformations(rot); Vec3 newz = rot.getColumn(2).getNormalized(); Vec3 newx = Vec3(0.0, 1.0, 0.0).cross(newz); Vec3 newy = newz.cross(newx); rot.setColumns(newx, newy, newz, Vec3(0.0)); rot.reorthogonalize(); // Update move move.setLocalTransform(Transform(origin, rot, 1.0)); } return ErrorCode::NONE; } }; //============================================================================== // PlayerNodeFeedbackComponent2 = //============================================================================== /// Feedback component. class PlayerNodeFeedbackComponent2 final: public SceneComponent { public: PlayerNodeFeedbackComponent2(SceneNode* node) : SceneComponent(SceneComponent::Type::NONE, node) {} Error update(SceneNode& node, F32, F32, Bool& updated) override { updated = false; PlayerControllerComponent& playerc = node.getComponent(); MoveComponent& move = node.getComponent(); const Input& in = node.getSceneGraph().getInput(); const F32 speed = 3.5; Vec4 moveVec(0.0); if(in.getKey(KeyCode::W)) { moveVec.z() += 1.0; } if(in.getKey(KeyCode::A)) { moveVec.x() -= 1.0; } if(in.getKey(KeyCode::S)) { moveVec.z() -= 1.0; } if(in.getKey(KeyCode::D)) { moveVec.x() += 1.0; } Vec4 dir = move.getLocalRotation().getColumn(2).xyz0(); dir.y() = 0.0; dir.normalize(); playerc.setVelocity( moveVec.z() * speed, moveVec.x() * speed, 0.0, dir); return ErrorCode::NONE; } }; //============================================================================== // PlayerNode = //============================================================================== //============================================================================== PlayerNode::PlayerNode(SceneGraph* scene) : SceneNode(scene) {} //============================================================================== PlayerNode::~PlayerNode() { if(m_player) { m_player->setMarkedForDeletion(); } } //============================================================================== Error PlayerNode::create(const CString& name, const Vec4& position) { Error err = SceneNode::create(name); if(err) { return err; } // Create physics object PhysicsPlayerController::Initializer init; init.m_position = position; m_player = getSceneGraph()._getPhysicsWorld().newPlayerController(init); SceneComponent* comp; // Player controller component comp = getSceneAllocator().newInstance( this, m_player); if(comp == nullptr) { return ErrorCode::OUT_OF_MEMORY; } err = addComponent(comp, true); if(err) { return err; } // Feedback component comp = getSceneAllocator().newInstance(this); if(comp == nullptr) { return ErrorCode::OUT_OF_MEMORY; } err = addComponent(comp, true); if(err) { return err; } // Move component comp = getSceneAllocator().newInstance(this); if(comp == nullptr) { return ErrorCode::OUT_OF_MEMORY; } err = addComponent(comp, true); if(err) { return err; } // Feedback component #2 comp = getSceneAllocator().newInstance(this); if(comp == nullptr) { return ErrorCode::OUT_OF_MEMORY; } err = addComponent(comp, true); if(err) { return err; } return err; } } // end namespace anki