I have a logic component derived class. I’m trying to figure out how the PostUpdate(float timestep) works. It works once but doesn’t repeat. Anyone know how to properly set a derived class to call Post Update.
I tried the both ways. Creating a virtual void PostUpdate function and also SubscribeToEvent E_SCENEPOSTUPDATE.
Both doesn’t work. It seems to only work on the component creation when its also added to a scene.
Vivienne
vivienneanthony
This is the code I have .
// Initialize
void ComputerCoreComponent::Initialize() {
// Debug
ALPHAENGINE_LOGINFO("Initialize Called");
// Get the Navigation Module
m_pNavigationModule = GetComponent<NavigationModuleComponent>();
// Bunch of code
// Subscribe to post update
SetUpdateEventMask(USE_POSTUPDATE);
// Subscribe to event
SubscribeToEvent(E_POSTUPDATE,
URHO3D_HANDLER(ComputerCoreComponent, HandlePostUpdate));
}
void ComputerCoreComponent::HandlePostUpdate(StringHash eventType,
VariantMap& eventData) {
if (m_pAutomatedVehicle) {
// Apply Linear Velocity
m_pAutomatedVehicle->ApplyLinearVelocity(m_LinearVelocity);
} else {
ALPHAENGINE_LOGINFO("Post Update Failed. No Automated Vehicle");
}
}
In the debug info “Post Update Failed. No Automated Vehicle” only appears once but it should show after each physics post update.
Enhex
You should do physics operations in the pre-step event.
E_SCENEPOSTUPDATE only applys to components which are part of a scene.
Your code isn’t helpful since we don’t know what sets m_pAutomatedVehicle.
It’s the first recommendation. It comes from a developer of Star Citizen on how they handle physics of ships.
The full code is below for the function. When the function is called it gets the component AutomatedVehicle and sets the pointer.
// Initialize
void ComputerCoreComponent::Initialize() {
// Debug
ALPHAENGINE_LOGINFO("Initialize Called");
// Get the Navigation Module
m_pNavigationModule = GetComponent<NavigationModuleComponent>();
// Get Automated Vechicle Component
m_pAutomatedVehicle = GetComponent<AutomatedVehicleComponent>();
// Get attached propulsion thrusters
PODVector<PropulsionThrusterComponent *> pPropulsionThrusters;
// Get Thrusters
GetNode()->GetComponents<PropulsionThrusterComponent>(pPropulsionThrusters,
true);
// Copy thrusters into memory
if (pPropulsionThrusters.Size() == 0) {
return;
} else {
if (m_pPropulsionThrusters.Size() == 0) {
// loop thoop each thruster and update
for (unsigned int i = 0; i < pPropulsionThrusters.Size(); i++) {
// copy each thruster
m_pPropulsionThrusters.Push(
(SharedPtr<PropulsionThrusterComponent> ) pPropulsionThrusters[i]);
}
}
}
// Subscribe to post update
SetUpdateEventMask(USE_POSTUPDATE);
// Subscribe to event
SubscribeToEvent(E_POSTUPDATE,
URHO3D_HANDLER(ComputerCoreComponent, HandlePostUpdate));
}
Enhex
it’s most likely you’re calling GetComponent<AutomatedVehicleComponent>() before you created that component.
You may need to use DelayedStart():
vivienneanthony
The automated class is this. Right now it’s a container component as I work on how the physics works.
/*
* AutomatedVehicle.cpp
*
* Created on: Feb 22, 2018
* Author: vivienne
*/
#include "HangarsClientStd.h"
#include "GameAsset/GAFactory.h"
#include "GameAsset/Components/PhysicsComponent/RigidBodyComponent/RigidBodyComponent.h"
// Add Computer Core to Automated Vehicle
#include "GameAssets/Components/AutomatedVehicle/AutomatedVehicleComponent.h"
#include "GameAssets/Components/ComputerCore/ComputerCoreComponent.h"
#include "GameAssets/Components/PropulsionThruster/PropulsionThrusterComponent.h"
#include "AlphaEngine/GameAsset/Components/PhysicsComponent/RigidBodyComponent/RigidBodyComponentEvent.h"
AutomatedVehicleComponent::AutomatedVehicleComponent(Context* context) :
LogicComponent(context), m_VehicleType(Vehicle_NULL), m_Name(""), m_pComputerCore(
nullptr), m_bInitialized(false), m_bLoadedXML(false) {
}
AutomatedVehicleComponent::~AutomatedVehicleComponent() {
//UnsubscribeFromAllEvents();
}
void AutomatedVehicleComponent::RegisterObject(Context* context) {
context->RegisterFactory<AutomatedVehicleComponent>();
}
bool AutomatedVehicleComponent::LoadXML(const XMLElement& source,
bool setInstanceDefault) {
ResourceCache* cache = g_pApp->GetConstantResCache();
// Get Name
XMLElement node = source.GetChild("UniqueID");
if (node) {
m_Name = node.GetAttribute("value").CString();
}
// Get Vehicle Type
node = source.GetChild("VehicleType");
if (node) {
m_VehicleType = (AutomatedVehicleType) node.GetUInt("value");
}
// Set Loaded XML
m_bLoadedXML = true;
return true;
}
bool AutomatedVehicleComponent::SaveXML(XMLElement& dest) const {
XMLElement componentNode = GAFactory::SaveComponentToXML(dest,
GetTypeName(), node_);
// Create name
XMLElement childNode = componentNode.CreateChild("UniqueID");
// Set the name
childNode.SetAttribute("value", String(m_Name.c_str()));
// Set vehicle type
childNode = componentNode.CreateChild("VehicleType");
// Set value
// NEED TO CONVERT
childNode.SetUInt("value", m_VehicleType);
return true;
}
// Process per frame
void AutomatedVehicleComponent::FixedUpdate(float timeStep) {
// If loaded XML and not initialized
if (m_bLoadedXML && m_bInitialized == false && node_)// Handle Per Frame Update
{
Initialize();
}
return;
}
void AutomatedVehicleComponent::Initialize() {
// Rigid Body
m_pRigidBody = GetComponent<RigidBodyComponent>();
// Get computer core
m_pComputerCore = GetComponent<ComputerCoreComponent>();
// Initialize computer core if attached
if (m_pComputerCore) {
m_pComputerCore->Initialize();
}
// // Get attached propulsion thrusters
// PODVector<PropulsionThrusterComponent *> pPropulsionThrusters;
//
// // Get Thrusters
// GetNode()->GetComponents<PropulsionThrusterComponent>(pPropulsionThrusters,
// true);
//
// // If thrusters detected
// if (int size = pPropulsionThrusters.Size()) {
// for (unsigned int i = 0; i < size; i++) {
// m_pPropulsionThrusters.push_back(pPropulsionThrusters[i]);
// }
// }
// If the computer core found and propulsion thruster size then m_bInitialized;
//if (!m_pComputerCore && !pPropulsionThrusters.Size()) {
if (!m_pComputerCore) {
// Set initialized to false
m_bInitialized = false;
} else {
m_bInitialized = true;
}
}
void AutomatedVehicleComponent::SetState(bool state) {
if (m_pComputerCore) {
m_pComputerCore->SetState(state);
}
}
void AutomatedVehicleComponent::InitializeAllDelegates() {
// Initialize
//Initialize();
// DEBUG LOG
//ALPHAENGINE_LOGINFO("Vehicle initialize delegates");
//SubscribeToEvent(E_NODECOLLISION, URHO3D_HANDLER(AutomatedVehicle, HandleCollisionBoxDelegate));
}
void AutomatedVehicleComponent::HandleCollisionBoxDelegate(StringHash eventType,
VariantMap& eventData) {
// Get Data
m_OtherNode =
static_cast<Node *>(eventData[RIGIDBODY_COLLISIONBOX::P_OTHERNODE].GetPtr());
//ALPHAENGINE_LOGINFO(node->GetName());
// Check if box hit gravity
if (m_OtherNode->GetName().Contains("BoxGravity")) {
ALPHAENGINE_LOGINFO("Ship hit box gravity");
}
}
// Apply Linear Velocity
void AutomatedVehicleComponent::ApplyLinearVelocity(Vector3 linearVelocity) {
}
// Apply Angular Velocity
void AutomatedVehicleComponent::ApplyAngularVelocity(Vector3 angularVelocity) {
}
// Apply Impulse
void AutomatedVehicleComponent::ApplyImpulse(Vector3 impulse) {
}
vivienneanthony
I’ll look. I’ll check but I should at least get some message “Post Update Failed. No Automated Vehicle” in the console log info repeatedly.
vivienneanthony
After taking a break. It was working as coded. I changed temporarily the intended way I would apply impulse. All good now.
vivienneanthony
This is for anyone but I found this code. It might be useful in a way just figuring the Urho3D translation.
I code I revised works some ignoring the whole cardinal system setup temporary. I am just setting longitude, latitude, and vertical movement. I’m using a similiar method like Star Citizen.
The key question will the code on the link help stabilize rotation in a scene that has gravity. Additionally,
I’m not sure of the equivalent. I think the link has a clue then afterward I could possible set the rotation to be Vector3::Identity * the Y axis angle
My current code is
// All Updates
void ComputerCoreComponent::Update(float timeStep) {
// If command buffer
if (m_CommandBuffer.size()) {
ComputerCoreCommand currentCommand = m_CommandBuffer.front();
// Output command
if (!currentCommand.command.Empty()) {
// ALPHAENGINE_LOGINFO(currentCommand.command);
}
// Ship Controls
if (currentCommand.command.Contains("Pitch+") == true) {
m_MovementPitch += .10;
if (m_MovementPitch > 1.0f)
m_MovementPitch = 1.0f;
}
if (currentCommand.command.Contains("Pitch-") == true) {
m_MovementPitch -= .10;
if (m_MovementPitch < -1.0f)
m_MovementPitch = -1.0f;
}
if (currentCommand.command.Contains("Longitude+") == true) {
m_MovementLongitude += .10;
if (m_MovementLongitude > 1.0f)
m_MovementLongitude = 1.0f;
}
if (currentCommand.command.Contains("Longitude-") == true) {
m_MovementLongitude -= .10;
if (m_MovementLongitude < -1.0f)
m_MovementLongitude = -1.0f;
}
if (currentCommand.command.Contains("Vertical+") == true) {
m_MovementVertical += .10;
if (m_MovementVertical > 1.0f)
m_MovementVertical = 1.0f;
}
if (currentCommand.command.Contains("Vertical-") == true) {
m_MovementVertical -= .10;
if (m_MovementVertical < -1.0f)
m_MovementVertical = -1.0f;
}
if (currentCommand.command.Contains("Latitude+") == true) {
m_MovementLatitude += .10;
if (m_MovementLatitude > 1.0f)
m_MovementLatitude = 1.0f;
}
if (currentCommand.command.Contains("Latitude-") == true) {
m_MovementLatitude -= .10;
if (m_MovementLatitude < -1.0f)
m_MovementLatitude = -1.0f;
}
if (currentCommand.command.Contains("Longitude+") == true) {
m_MovementLongitude += .10;
if (m_MovementLongitude > 1.0f)
m_MovementLongitude = 1.0f;
}
if (currentCommand.command.Contains("Longitude-") == true) {
m_MovementLongitude -= .10;
if (m_MovementLongitude < -1.0f)
m_MovementLongitude = -1.0f;
}
if (currentCommand.command.Contains("Vertical+") == true) {
m_MovementVertical += .10;
if (m_MovementVertical > 1.0f)
m_MovementVertical = 1.0f;
}
if (currentCommand.command.Contains("Vertical-") == true) {
m_MovementVertical -= .10;
if (m_MovementVertical < -1.0f)
m_MovementVertical = -1.0f;
}
// Clear Command Buffer
m_CommandBuffer.clear();
}
// Convert Movement to Velocity
ConvertMovementToVelocity();
}
// Set State of modules
void ComputerCoreComponent::SetState(bool state) {
// If navigation module
if (m_pNavigationModule) {
m_pNavigationModule->SetState(state);
}
}
void ComputerCoreComponent::HandlePostUpdate(StringHash eventType,
VariantMap& eventData) {
if (m_pAutomatedVehicle) {
if (m_LinearVelocity != Vector3::ZERO) {
// Apply Linear Velocity
m_pAutomatedVehicle->ApplyImpulse(m_LinearVelocity);
// Reset all forces
m_MovementLatitude = m_MovementLongitude = m_MovementVertical = 0.0f;
}
} else {
ALPHAENGINE_LOGINFO("Post Update Failed. No Automated Vehicle");
}
}
// Convert Movement to Velocity
void ComputerCoreComponent::ConvertMovementToVelocity() {
// Create a zero vector
Vector3 LinearVelocity = Vector3::ZERO;
// Calculate impulse amount by Latitiude, Vertical, and Longititude
LinearVelocity = Vector3(m_MovementLatitude * 2, m_MovementVertical * 2,
m_MovementLongitude * 2);
// Set Linear Velocity Impulse
m_LinearVelocity = LinearVelocity;
}
vivienneanthony
Sorry. I know its a lot of question. I’m reading docs and pdf’s and it’s semi gibberish. I visually can see what to do but seeing a bunch formulas ins’t help.
The non-gibberish method. I would think is get the current rotation and velocity. Multiply the rotation by velocity and inverse it. Setting the angular velocity. Then next frame or after simply set the angular velocity to Identity or Identity times the Y axis rotation. If gravity exist.