[SOLVED]how do you go about collison check?

hi,

my project start to looks like something but i need to do some collision check

after checking the wiki, i think that for each of my module, i need to add this to get a precise bounding box

//add physic        dont forget to include RigidBody and CollisionShape
        RigidBody* m_Body=moduleNode->CreateComponent<RigidBody>();
        m_Body->SetMass(0);  //0 for static object
        m_Body->SetFriction(0.6);        // friction with other objects (like the ground)
//add collision shape
        CollisionShape* m_BBox=moduleNode->CreateComponent<CollisionShape>();      
        m_BBox->SetTriangleMesh(cache->GetResource<Model>(path));

then i can use layers

m_body->SetCollisionLayer(2)

but how do you do a collision check between two bounding box ? what must i use ?
so that if a module spawn on another, i change it or delete it or whatever.

and by the way, i have a little question : is there a way to get a list of all the scene child ?

thx

i found this page : urho3d.github.io/documentation/1.5/_physics.html that direct me to GetCollidingBodies()

so i guess it could work with :

if(m_Body->GetCollidingBodies() != 0)  //or NULL ?
{
    //there is a collision with another module : do something.
}
else
{
    //there is no collision, the module can stay here.
}

i will try that and see.

in my project iam working with the E_NODECOLLISION event.

[code]
SubscribeToEvent(mynode, E_NODECOLLISION, HANDLER(objectevents, HandleObjectCollision)); //for every node that should trigger something on collision

void objectevents::HandleObjectCollision(StringHash eventT, VariantMap& eData)
{
RigidBody* body = static_cast<RigidBody*>(eData[P_BODY].GetPtr());
Component* comp;
comp=body->GetComponent(“StaticModel”);
Node* myobject;
myobject=comp->GetNode ();

}[/code]

I have a xml file looks like this to load and subscribe the events per level in a function:

[code]<?xml version="1.0"?>



[/code]

your method seems a bit complicated to me but thx anyway. i didn’t tryed anything yet, i will check it out later, the SubscribeToEvent could be usefull.

yep i try to don’t hardcode too much in my game, so i need this xml solution. You can do it with urho node variables too, or just hardcode it :wink:

and yep you will need SubscribeToEvent.

You can also only subscribe your mainchar and look with what he collude. (setting variables or names to the nodes to choose the trigger), but then your objects don’t interact between each other

Hi,
Scene::GetChildren() is one way.
Here is a quick and dirty recursive print method, copypasta untested, Using Urho head revision… should not be too different for 1.5.
Scene is a type of Node, so this works with both types.

[details=Code][code]
decl:
void PrintTree(Urho3D::Node* node, unsigned level = 0);

void SceneManager::PrintTree(Node* node, unsigned level /* = 0 */) {
// if you do not like spam
// if (node->HasComponent()) return;

String s(’+’, level); // indentation
s += “<” + node->GetName() + “>” + " pos:" + String(node->GetPosition());

URHO3D_LOGRAW(s + ‘\n’); // opt. URHO3D_LOGINFO etc.

if (!node->GetChildren().Empty()) {
const Vector<SharedPtr> children(node->GetChildren()); // pre-C++11 needs a space: <SharedPtr >
for (unsigned i = 0; i < children.Size(); ++i) {
PrintTree(children[i], level + 1);
}
}
}
[/code][/details]

[quote=“Nerrik”]

yep i try to don’t hardcode too much in my game, so i need this xml solution. You can do it with urho node variables too, or just hardcode it :wink:

and yep you will need SubscribeToEvent.

You can also only subscribe your mainchar and look with what he collude. (setting variables or names to the nodes to choose the trigger), but then your objects don’t interact between each other[/quote]
i also use xml, i code so that when it is compiled, you can just change the modules at your liking with the xml. (or other things later)

i didn’t do a character yet but i know i will at least need 3 physics layer because i think modules side by side would return a collision==true;

[quote=“carnalis”]

Hi,
Scene::GetChildren() is one way.
Here is a quick and dirty recursive print method, copypasta untested, Using Urho head revision… should not be too different for 1.5.
Scene is a type of Node, so this works with both types.

[spoiler][code]
decl:
void PrintTree(Urho3D::Node* node, unsigned level = 0);

void SceneManager::PrintTree(Node* node, unsigned level /* = 0 */) {
// if you do not like spam
// if (node->HasComponent()) return;

String s(’+’, level); // indentation
s += “<” + node->GetName() + “>” + " pos:" + String(node->GetPosition());

URHO3D_LOGRAW(s + ‘\n’); // opt. URHO3D_LOGINFO etc.

if (!node->GetChildren().Empty()) {
const Vector<SharedPtr> children(node->GetChildren()); // pre-C++11 needs a space: <SharedPtr >
for (unsigned i = 0; i < children.Size(); ++i) {
PrintTree(children[i], level + 1);
}
}
}
[/code][/spoiler][/quote]
ah ok, so you can make a vector of children and incremente until your pointer is* empty when you get them from the scene. thx, that’s good to know. (edit: i reread and the node method too is good to know ^^)
*edit 2 ><

i go do some tries, i also need to check the physic demo to see what #include i need, etc…

1 Like

another question, is it possible to change the color of the collision layer when i render it ? how should i do ?
in the physic example, you can use the SPACE key to see the physic stuff so i put different layers for the first module and the others module but i can’t see the difference when rendering.

there is also an NodeCollisionEnd event, to handle double collisions if you mean that. (with an “lastcollision” array or something like this).

i saw that in the doc : http://urho3d.github.io/documentation/1.5/_event_list.html

so if the two RigidBody are side by side, i can define them as “false” so they will not be seen as colliding ?
yes i would need that, thx.
but how do i use it ?

[quote](with an “lastcollision” array or something like this)[/quote] ?
i’m lost already lol.

i put the m_Body on the same layer and i will try that tomorrow :

[code] c_light=scene->CreateChild(“collision_light”);
c_light->SetPosition(Vector3(position.x_, position.y_+1, position.z_));
{
Light* Elight=e_light->CreateComponent();
Elight->SetLightType(LIGHT_POINT);
Elight->SetRange(2);

        if(m_Body->GetCollidingBodies() != 0)  //or NULL ?
        {
            //there is a collision with another module : do something.
            Elight->SetBrightness(2.0);
            Elight->SetColor(Color(1.0,0.5,0.1,1.0));
        }
        else
        {
            //there is no collision, the module can stay here.
            Elight->SetBrightness(2.0);
            Elight->SetColor(Color(.0,.0,1.0,1.0));
        }
    }[/code]

i should see an orange or a blue light if it work at all.

ok, i just understood that i need to check the somethingEvents.h in the source with the documentation to see what’s going on but it’s still confusing to me.

[code]
SubscribeToEvent(mynode, E_NODECOLLISION, HANDLER(objectevents, HandleObjectCollision)); //for every node that should trigger something on collision

void objectevents::HandleObjectCollision(StringHash eventT, VariantMap& eData)
{
RigidBody* body = static_cast<RigidBody*>(eData[P_BODY].GetPtr());[/code]

mynode ? why are you able to put it in the SubscribeToEvent() ?
can i name HandleObjectCollision as i want ?
and so, eData[P_BODY].GetPtr() point to what excatly ?

first of all, there was some 1.5 changes:

SubscribeToEvent(mynode, E_NODECOLLISION, HANDLER(objectevents, HandleObjectCollision)); 

should be written:

SubscribeToEvent(mynode, E_NODECOLLISION, URHO3D_HANDLER(objectevents, HandleObjectCollision));

mynode ? why are you able to put it in the SubscribeToEvent() ?

if it has a RigidBody and a CollisionShape, you’ll can set this event on every node you want.

can i name HandleObjectCollision as i want ?
yes (Also different notes to different functions)

and so, eData[P_BODY].GetPtr() point to what excatly ?

to the RigidBody of the collision target. (node rbody that get colluded by something)

URHO3D_EVENT(E_NODECOLLISION, NodeCollision)
{
    URHO3D_PARAM(P_BODY, Body);                    // RigidBody pointer
    URHO3D_PARAM(P_OTHERNODE, OtherNode);          // Node pointer
    URHO3D_PARAM(P_OTHERBODY, OtherBody);          // RigidBody pointer
    URHO3D_PARAM(P_TRIGGER, Trigger);              // bool
    URHO3D_PARAM(P_CONTACTS, Contacts);            // Buffer containing position (Vector3), normal (Vector3), distance (float), impulse (float) for each contact
}

This class method is described in the docs, events subsection Sending events through another object
urho3d.github.io/documentation/H … therObject
urho3d.github.io/documentation/1 … therObject (1.5 - same)

I think that section could be clearer by giving an example of the method.

this SubscribeToEvent(mynode, E_NODECOLLISION, HANDLER(objectevents, HandleObjectCollision))
is actually : SubscribeToEvent(mynode, P_BODY, P_OTHERNODE, P_OTHERBODY, P_TRIGGER, P_CONTACTS, HANDLER(objectevents, HandleObjectCollision))
and im starting to get the idea but i will need to test things up anyway.

yes, that’s what i meant. i wasn’t able to find it in the doc at this time, thx.
i though we were able to put whatever we wanted in the function somehow.

yeah an exemple would be nice through i will still try the other thing again later as well

i’m rethinking my whole code now, i need a better organisation.

come home from a party and iam drunk, but have extended the 11_Physics (1.5) sample a little bit…just search for “//itsnew” replace the code and watch in to the log (F1)

11_Physics.h
//
// Copyright (c) 2008-2015 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#pragma once

#include "Sample.h"

namespace Urho3D
{

class Node;
class Scene;

}
    using namespace NodeCollision; //itsnew
/// Physics example.
/// This sample demonstrates:
///     - Creating both static and moving physics objects to a scene
///     - Displaying physics debug geometry
///     - Using the Skybox component for setting up an unmoving sky
///     - Saving a scene to a file and loading it to restore a previous state
class Physics : public Sample
{
    URHO3D_OBJECT(Physics, Sample);

public:
    /// Construct.
    Physics(Context* context);

    /// Setup after engine initialization and before running the main loop.
    virtual void Start();

protected:
    /// Return XML patch instructions for screen joystick layout for a specific sample app, if any.
    virtual String GetScreenJoystickPatchString() const { return
        "<patch>"
        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/attribute[@name='Is Visible']\" />"
        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Spawn</replace>"
        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]\">"
        "        <element type=\"Text\">"
        "            <attribute name=\"Name\" value=\"MouseButtonBinding\" />"
        "            <attribute name=\"Text\" value=\"LEFT\" />"
        "        </element>"
        "    </add>"
        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/attribute[@name='Is Visible']\" />"
        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Debug</replace>"
        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]\">"
        "        <element type=\"Text\">"
        "            <attribute name=\"Name\" value=\"KeyBinding\" />"
        "            <attribute name=\"Text\" value=\"SPACE\" />"
        "        </element>"
        "    </add>"
        "</patch>";
    }

private:
    /// Construct the scene content.
    void CreateScene();
    /// Construct an instruction text to the UI.
    void CreateInstructions();
    /// Set up a viewport for displaying the scene.
    void SetupViewport();
    /// Subscribe to application-wide logic update and post-render update events.
    void SubscribeToEvents();
    /// Read input and moves the camera.
    void MoveCamera(float timeStep);
    /// Spawn a physics object from the camera position.
    void SpawnObject();
    /// Handle the logic update event.
    void HandleUpdate(StringHash eventType, VariantMap& eventData);
    /// Handle the post-render update event.
    void HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData);
    void HandleObjectCollision(StringHash eventType, VariantMap& eventData); //itsnew
    /// Flag for drawing debug geometry.
    bool drawDebug_;
};
11_Physics.cpp
//
// Copyright (c) 2008-2015 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Engine/Engine.h>
#include <Urho3D/Graphics/Camera.h>
#include <Urho3D/Graphics/DebugRenderer.h>
#include <Urho3D/Graphics/Graphics.h>
#include <Urho3D/Graphics/Light.h>
#include <Urho3D/Graphics/Material.h>
#include <Urho3D/Graphics/Model.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/Graphics/Skybox.h>
#include <Urho3D/Graphics/Zone.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/IO/File.h>
#include <Urho3D/IO/FileSystem.h>
#include <Urho3D/Physics/CollisionShape.h>
#include <Urho3D/Physics/PhysicsWorld.h>
#include <Urho3D/Physics/RigidBody.h>
#include <Urho3D/Physics/PhysicsEvents.h> //itsnew
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Scene/Scene.h>
#include <Urho3D/UI/Font.h>
#include <Urho3D/UI/Text.h>
#include <Urho3D/UI/UI.h>
#include <Urho3D/IO/Log.h> //itsnew
#include "Physics.h"

#include <Urho3D/DebugNew.h>

URHO3D_DEFINE_APPLICATION_MAIN(Physics)


Physics::Physics(Context* context) :
    Sample(context),
    drawDebug_(false)
{
}

void Physics::Start()
{
    // Execute base class startup
    Sample::Start();

    // Create the scene content
    CreateScene();

    // Create the UI content
    CreateInstructions();

    // Setup the viewport for displaying the scene
    SetupViewport();

    // Hook up to the frame update and render post-update events
    SubscribeToEvents();
}

void Physics::CreateScene()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);

    // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
    // Create a physics simulation world with default parameters, which will update at 60fps. Like the Octree must
    // exist before creating drawable components, the PhysicsWorld must exist before creating physics components.
    // Finally, create a DebugRenderer component so that we can draw physics debug geometry
    scene_->CreateComponent<Octree>();
    scene_->CreateComponent<PhysicsWorld>();
    scene_->CreateComponent<DebugRenderer>();

    // Create a Zone component for ambient lighting & fog control
    Node* zoneNode = scene_->CreateChild("Zone");
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    zone->SetFogColor(Color(1.0f, 1.0f, 1.0f));
    zone->SetFogStart(300.0f);
    zone->SetFogEnd(500.0f);

    // Create a directional light to the world. Enable cascaded shadows on it
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetCastShadows(true);
    light->SetShadowBias(BiasParameters(0.00025f, 0.5f));
    // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance
    light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));

    // Create skybox. The Skybox component is used like StaticModel, but it will be always located at the camera, giving the
    // illusion of the box planes being far away. Use just the ordinary Box model and a suitable material, whose shader will
    // generate the necessary 3D texture coordinates for cube mapping
    Node* skyNode = scene_->CreateChild("Sky");
    skyNode->SetScale(500.0f); // The scale actually does not matter
    Skybox* skybox = skyNode->CreateComponent<Skybox>();
    skybox->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
    skybox->SetMaterial(cache->GetResource<Material>("Materials/Skybox.xml"));

    {
        // Create a floor object, 1000 x 1000 world units. Adjust position so that the ground is at zero Y
        Node* floorNode = scene_->CreateChild("Floor");
        floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));
        floorNode->SetScale(Vector3(1000.0f, 1.0f, 1000.0f));
        StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
        floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));

        // Make the floor physical by adding RigidBody and CollisionShape components. The RigidBody's default
        // parameters make the object static (zero mass.) Note that a CollisionShape by itself will not participate
        // in the physics simulation
        /*RigidBody* body = */floorNode->CreateComponent<RigidBody>();
        CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
        // Set a box shape of size 1 x 1 x 1 for collision. The shape will be scaled with the scene node scale, so the
        // rendering and physics representation sizes should match (the box model is also 1 x 1 x 1.)
        shape->SetBox(Vector3::ONE);
    }

    {
        // Create a pyramid of movable physics objects
        for (int y = 0; y < 8; ++y)
        {
            for (int x = -y; x <= y; ++x)
            {
                int z=0;
                String MyBoxname = "x:" + (String)float(x) + ", y:" + (String)-(float(y + 8.0f))+", z:" + (String)float(z); //itsnew - generate a unique name (starting position)
                Node* boxNode = scene_->CreateChild(MyBoxname); //itsnew
                boxNode->SetPosition(Vector3((float)x, -(float)y + 8.0f, 0.0f));
                StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
                boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
                boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneEnvMapSmall.xml"));
                boxObject->SetCastShadows(true);

                // Create RigidBody and CollisionShape components like above. Give the RigidBody mass to make it movable
                // and also adjust friction. The actual mass is not important; only the mass ratios between colliding
                // objects are significant
                RigidBody* body = boxNode->CreateComponent<RigidBody>();
                body->SetMass(1.0f);
                body->SetFriction(0.75f);
                CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
                shape->SetBox(Vector3::ONE);
                SubscribeToEvent(boxNode, E_NODECOLLISION, URHO3D_HANDLER(Physics, HandleObjectCollision)); //itsnew
            }
        }
    }

    // Create the camera. Set far clip to match the fog. Note: now we actually create the camera node outside the scene, because
    // we want it to be unaffected by scene load / save
    cameraNode_ = new Node(context_);
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(500.0f);

    // Set an initial position for the camera scene node above the floor
    cameraNode_->SetPosition(Vector3(0.0f, 5.0f, -20.0f));
}

void Physics::CreateInstructions()
{

    ResourceCache* cache = GetSubsystem<ResourceCache>();
    UI* ui = GetSubsystem<UI>();

    // Construct new Text object, set string to display and font to use
    Text* instructionText = ui->GetRoot()->CreateChild<Text>();
    instructionText->SetText(
        "Use WASD keys and mouse/touch to move\n"
        "LMB to spawn physics objects\n"
        "F5 to save scene, F7 to load\n"
        "Space to toggle physics debug geometry"
    );
    instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15);
    // The text has multiple rows. Center them in relation to each other
    instructionText->SetTextAlignment(HA_CENTER);

    // Position the text relative to the screen center
    instructionText->SetHorizontalAlignment(HA_CENTER);
    instructionText->SetVerticalAlignment(VA_CENTER);
    instructionText->SetPosition(0, ui->GetRoot()->GetHeight() / 4);
}

void Physics::SetupViewport()
{
    Renderer* renderer = GetSubsystem<Renderer>();

    // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
    SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
    renderer->SetViewport(0, viewport);
}

void Physics::SubscribeToEvents()
{
    // Subscribe HandleUpdate() function for processing update events
    SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(Physics, HandleUpdate));

    // Subscribe HandlePostRenderUpdate() function for processing the post-render update event, during which we request
    // debug geometry
    SubscribeToEvent(E_POSTRENDERUPDATE, URHO3D_HANDLER(Physics, HandlePostRenderUpdate));
}

void Physics::MoveCamera(float timeStep)
{
    // Do not move if the UI has a focused element (the console)
    if (GetSubsystem<UI>()->GetFocusElement())
        return;

    Input* input = GetSubsystem<Input>();

    // Movement speed as world units per second
    const float MOVE_SPEED = 20.0f;
    // Mouse sensitivity as degrees per pixel
    const float MOUSE_SENSITIVITY = 0.1f;

    // Use this frame's mouse motion to adjust camera node yaw and pitch. Clamp the pitch between -90 and 90 degrees
    IntVector2 mouseMove = input->GetMouseMove();
    yaw_ += MOUSE_SENSITIVITY * mouseMove.x_;
    pitch_ += MOUSE_SENSITIVITY * mouseMove.y_;
    pitch_ = Clamp(pitch_, -90.0f, 90.0f);

    // Construct new orientation for the camera scene node from yaw and pitch. Roll is fixed to zero
    cameraNode_->SetRotation(Quaternion(pitch_, yaw_, 0.0f));

    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
    if (input->GetKeyDown('W'))
        cameraNode_->Translate(Vector3::FORWARD * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('S'))
        cameraNode_->Translate(Vector3::BACK * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('A'))
        cameraNode_->Translate(Vector3::LEFT * MOVE_SPEED * timeStep);
    if (input->GetKeyDown('D'))
        cameraNode_->Translate(Vector3::RIGHT * MOVE_SPEED * timeStep);

    // "Shoot" a physics object with left mousebutton
    if (input->GetMouseButtonPress(MOUSEB_LEFT))
        SpawnObject();

    // Check for loading/saving the scene. Save the scene to the file Data/Scenes/Physics.xml relative to the executable
    // directory
    if (input->GetKeyPress(KEY_F5))
    {
        File saveFile(context_, GetSubsystem<FileSystem>()->GetProgramDir() + "Data/Scenes/Physics.xml", FILE_WRITE);
        scene_->SaveXML(saveFile);
    }
    if (input->GetKeyPress(KEY_F7))
    {
        File loadFile(context_, GetSubsystem<FileSystem>()->GetProgramDir() + "Data/Scenes/Physics.xml", FILE_READ);
        scene_->LoadXML(loadFile);
    }

    // Toggle physics debug geometry with space
    if (input->GetKeyPress(KEY_SPACE))
        drawDebug_ = !drawDebug_;
}

void Physics::SpawnObject()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    // Create a smaller box at camera position
    Node* boxNode = scene_->CreateChild("SmallBox");
    boxNode->SetPosition(cameraNode_->GetPosition());
    boxNode->SetRotation(cameraNode_->GetRotation());
    boxNode->SetScale(0.25f);
    StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
    boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
    boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneEnvMapSmall.xml"));
    boxObject->SetCastShadows(true);

    // Create physics components, use a smaller mass also
    RigidBody* body = boxNode->CreateComponent<RigidBody>();
    body->SetMass(0.25f);
    body->SetFriction(0.75f);
    CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
    shape->SetBox(Vector3::ONE);

    const float OBJECT_VELOCITY = 10.0f;

    // Set initial velocity for the RigidBody based on camera forward vector. Add also a slight up component
    // to overcome gravity better
    body->SetLinearVelocity(cameraNode_->GetRotation() * Vector3(0.0f, 0.25f, 1.0f) * OBJECT_VELOCITY);
}

void Physics::HandleUpdate(StringHash eventType, VariantMap& eventData)
{
    using namespace Update;

    // Take the frame time step, which is stored as a float
    float timeStep = eventData[P_TIMESTEP].GetFloat();

    // Move the camera, scale movement with time step
    MoveCamera(timeStep);
}

void Physics::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
    // If draw debug mode is enabled, draw physics debug geometry. Use depth test to make the result easier to interpret
    if (drawDebug_)
        scene_->GetComponent<PhysicsWorld>()->DrawDebugGeometry(true);
}


//itsnew all now.......


void Physics::HandleObjectCollision(StringHash eventT, VariantMap& eData)
{

RigidBody* body = static_cast<RigidBody*>(eData[P_BODY].GetPtr());
Component* comp;
comp=body->GetComponent("StaticModel");
Node* myobject;
myobject=comp->GetNode ();
String nodename=myobject->GetName();


Node* otherNode = static_cast<Node*>(eData[P_OTHERNODE].GetPtr());
String othernodename=otherNode->GetName();

URHO3D_LOGRAW("\n nodename: " + nodename + " collude with: " + othernodename);


}

its no rockedsience…

1 Like

it took me some time but i rewrited my stuff and i tryed your method to see what it actually does but it doesn’t seem to return anything at all.
i just got this message in the terminal :

[quote]warning btCollisionDispatcher::needsCollision: static-static collision!
[/quote]
i guess i need a static-static collision test but that don’t help me much at this point.
what should i use ?

the code i tryed :

        SubscribeToEvent(E_NODECOLLISION, URHO3D_HANDLER(projet, HandleCollisionUpdate)); //collision test  

    void HandleCollisionUpdate(StringHash eventType, VariantMap& eventData)
    {

        RigidBody* body = static_cast<RigidBody*>(eventData[P_BODY].GetPtr());
        Component* comp;
        comp=body->GetComponent("AnimatedModel");
        Node* myobject;
        myobject=comp->GetNode ();
        String nodename=myobject->GetName();


        Node* otherNode = static_cast<Node*>(eventData[P_OTHERNODE].GetPtr());
        String othernodename=otherNode->GetName();

        URHO3D_LOGRAW("\n nodename: " + nodename + " collide with: " + othernodename);
    }

you dont give the SubscribeToEvent a node.
SubscribeToEvent(E_NODECOLLISION, URHO3D_HANDLER(projet, HandleCollisionUpdate)); //collision test

but you have set this event to a specific node that should send this event on a collision (with whatever)

nodes: http://urho3d.github.io/documentation/1.3/class_urho3_d_1_1_node.html

SubscribeToEvent(boxNode, E_NODECOLLISION, URHO3D_HANDLER(Physics, HandleObjectCollision)); //itsnew

this nodes also should have a rigidbody: http://urho3d.github.io/documentation/1.5/class_urho3_d_1_1_rigid_body.html
and a collisionshape: http://urho3d.github.io/documentation/1.5/class_urho3_d_1_1_collision_shape.html

AND

void HandleCollisionUpdate(StringHash eventType, VariantMap& eventData)

normaly it should be wirtten:
void YOURCLASSNAME::HandleCollisionUpdate(StringHash eventType, VariantMap& eventData)

so

SubscribeToEvent(boxNode, E_NODECOLLISION, URHO3D_HANDLER(YOURCLASSNAME, HandleObjectCollision)); //itsnew

can point to the right class and function(void)

ok, sorry if i’m annoying but be rassured that i am as much or even more annoyed than you could be.
this shit doesn’t really make sense to me when trying to include it in my code so i will describe what i understand and what i don’t plus my actual problem in hope you will can enlight me.

first of all, i have my urho3D main class that represent my project :

class projet : public Application
{
    URHO3D_OBJECT(projet, Application)

and within the virtual void Start(), i have the SubscribeToEvent stuff including :

SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(projet, HandleUpdate)); SubscribeToEvent(E_POSTRENDERUPDATE,URHO3D_HANDLER(projet,HandlePostRenderUpdate)); SubscribeToEvent(E_KEYDOWN, URHO3D_HANDLER(projet, HandleKeyDown));
so no problem here.

then, i have a “Dungeon” class in separates files that use r_Rooms (for random rooms), r_Cors (for random corridors), r_Juncs (for random junctions) and Module classes to build the dungeon.
example, the first loaded module :

Dungeon::Dungeon(int MODULE_MAX, Scene* scene, ResourceCache* cache)
{
   MODULE_COUNT = 0;
   roomJuncSwitch = 0;

   while(MODULE_COUNT<MODULE_MAX)
   {
       if(mainExitList.size()==0)
       {
            room_p = new r_Rooms(); //i start with a room
            module_p = new Module(MODULE_COUNT, room_p->type, room_p->std_name, 
                                  room_p->exits, room_p->path, room_p->texturepath,
                                  scene, cache);
            
            for(int x=0;x<module_p->exitList.size();x++)
            {
                mainExitList.push_back(module_p->exitList[x]);
            }       

            temp_Body = module_p->m_Body;  
            MODULE_COUNT++;
        }
        else
        {

each module object have its Node, AnimatedModel, RigidBody and CollisionShape that i can access with the pointer module_p-> and that should be this node that is collision tested for each loaded module…
so i need to put the subscribeToEvent stuff within my class i guess but that’s where i don’t really get it.

if i want to make a fonction within my class, first i declare it as a public member :

and then, in the .cpp, i can define what the function does :

void Dungeon::testCollision(Node* whatever) { collisionTest(whatever); }

but here, i guess i should have something like this in my class.h public member :

but i also guess it won’t work if it isn’t define in the projet class so i’m not sure how to use it
and for the function :

[code]void Dungeon(?)::HandleCollisionUpdate(StringHash eventType, VariantMap& eventData)
{

    RigidBody* body = static_cast<RigidBody*>(eventData[P_BODY].GetPtr());
    Component* comp;
    comp=body->GetComponent("AnimatedModel");
    Node* myobject;
    myobject=comp->GetNode ();
    String nodename=myobject->GetName();[/code]

i guess i have to put it in my class.cpp somehow but since it’s a function definition, can i put it in the constructor of my class ?
anyway, i kinda understand a few things but with this method i’m lost, i don’t know where to put what because i don’t need it in the main.cpp and the way the function is defined just confuse me.

you have the main.cpp, the class.h and the class.cpp. what do you write in each stuff for an event to work ?

Thats because you doing it wrong.Are you trying to make a wrapper or i can’t really understand what are you trying to do ? :confused:

You don’t have SubscribeToEvent in your class because its not derived from Urho3D::Object… Here are few advices :

Get rid of these Module , Dungeon and other classes you try to implement.You don’t need them. Urho doesn’t work this way. Follow the rules that the developers provided.In this case Component based programming.
Instead of creating a Dungeon and other external classes , you should use Urho3d::Node and add your collision body , AnimatedModel etc components to it. Define a Corridor , and Dungeon components derived from Urho3D::LogicComponent. Now you have a valid Urho Object that can properly subscribed to events , collision checks and network updates.