Skip to content

Instantly share code, notes, and snippets.

@darkuranium
Last active May 9, 2017 16:12
Show Gist options
  • Save darkuranium/a75853e7c99e57bcbc12f3d0c5b1b670 to your computer and use it in GitHub Desktop.
Save darkuranium/a75853e7c99e57bcbc12f3d0c5b1b670 to your computer and use it in GitHub Desktop.
Problem MCVE for Urho3D instancing issue
// Enable this to work around the problem.
//#define COMPILE_WORKAROUND
#ifdef _MSC_VER
#pragma warning( disable : 4005 ) // macro redefinition for URHO3D_STATIC_DEFINE and URHO3D_SSE in <Urho3D/Urho3D.h>
#endif
#include <Urho3D/Urho3D.h>
#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Engine/Application.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Scene/Scene.h>
#include <Urho3D/Graphics/Camera.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/Graphics/DebugRenderer.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/Model.h>
#include <Urho3D/Graphics/StaticModel.h>
#include <Urho3D/Graphics/Material.h>
#include <Urho3D/Graphics/Zone.h>
#ifdef _MSC_VER
#pragma warning( default : 4005 )
#endif
using namespace Urho3D;
class ProblemMCVE : public Application
{
public:
SharedPtr<Scene> scene_;
Node* cameraNode_;
Urho3D::Camera* camera_;
/*
Any pair of objects with same model *and* material will be disappearing and reappearing as the camera is moved.
Workaround: ->Clone() the material.
*/
SharedPtr<Node> node_a; // okay (Sphere+Stone)
SharedPtr<Node> node_b; // okay (Sphere+default)
SharedPtr<Node> node_c; // disappearing (Sphere+Mushroom)
SharedPtr<Node> node_d; // disappearing (Sphere+Mushroom)
// ... if the model of (say) d is changed, then c&d work, even with the same (non-cloned) material!
ProblemMCVE(Context* context) : Application(context) { }
virtual void Setup()
{
engineParameters_["FullScreen"] = false;
engineParameters_["WindowWidth"] = 1280;
engineParameters_["WindowHeight"] = 720;
engineParameters_["WindowResizable"] = true;
}
virtual void Start()
{
ResourceCache* cache=GetSubsystem<ResourceCache>();
scene_=new Scene(context_);
scene_->CreateComponent<Octree>();
//scene_->CreateComponent<DebugRenderer>();
cameraNode_=scene_->CreateChild("Camera");
camera_=cameraNode_->CreateComponent<Camera>();
Renderer* renderer=GetSubsystem<Renderer>();
SharedPtr<Viewport> viewport(new Viewport(context_,scene_,cameraNode_->GetComponent<Camera>()));
renderer->SetViewport(0,viewport);
// Note: Problem remains even without the zone, but I've kept it because otherwise, things are hard to see.
Node* zoneNode=scene_->CreateChild("Zone");
Zone* zone=zoneNode->CreateComponent<Zone>();
zone->SetBoundingBox(BoundingBox(-50000.0f, 50000.0f));
zone->SetFogStart(500.0f);
zone->SetFogEnd(600.0f);
zone->SetFogColor(Color(0.0f, 0.0f, 0.0f));
zone->SetAmbientColor(Color(1.0f, 1.0f, 1.0f));
SubscribeToEvent(E_KEYDOWN, URHO3D_HANDLER(ProblemMCVE, HandleKeyDown));
SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(ProblemMCVE, HandleUpdate));
cameraNode_->SetPosition(Vector3(0.0f, 0.0f, 0.0f));
cameraNode_->SetDirection(Vector3::FORWARD);
{
node_a = scene_->CreateChild();
node_a->SetPosition(Vector3(0.0f, 1.6f, 6.0f));
StaticModel* boxObject = node_a->CreateComponent<StaticModel>();
boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl"));
boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
}
{
node_b = scene_->CreateChild();
node_b->SetPosition(Vector3(0.0f, 10.0f, 6.0f));
StaticModel* boxObject = node_b->CreateComponent<StaticModel>();
boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl"));
}
#ifdef COMPILE_WORKAROUND
Material* mtlC;
#endif
// disappearing without workaround
{
node_c = scene_->CreateChild();
node_c->SetPosition(Vector3(0.0f, 6.0f, 6.0f));
StaticModel* boxObject = node_c->CreateComponent<StaticModel>();
boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl"));
#ifdef COMPILE_WORKAROUND
mtlC = cache->GetResource<Material>("Materials/Mushroom.xml");
boxObject->SetMaterial(mtlC);
#else
boxObject->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml"));
#endif
}
// disappearing without workaround
{
node_d =scene_->CreateChild("Planet");
node_d->SetPosition(Vector3(-4.0f, 1.6f, 6.0f));
node_d->SetScale(2);
StaticModel* boxObject = node_d->CreateComponent<StaticModel>();
boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl"));
#ifdef COMPILE_WORKAROUND
boxObject->SetMaterial(mtlC->Clone());
#else
boxObject->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml"));
#endif
}
}
virtual void Stop()
{
}
void HandleUpdate(StringHash eventType,VariantMap& eventData)
{
float timeStep=eventData[Update::P_TIMESTEP].GetFloat();
// Movement speed as world units per second
float MOVE_SPEED=10.0f;
// Mouse sensitivity as degrees per pixel
const float MOUSE_SENSITIVITY=0.1f;
// camera movement
Input* input=GetSubsystem<Input>();
if(input->GetQualifierDown(1)) // 1 is shift, 2 is ctrl, 4 is alt
MOVE_SPEED*=10;
if(input->GetKeyDown('W'))
cameraNode_->Translate(Vector3(0,0, 1)*MOVE_SPEED*timeStep);
if(input->GetKeyDown('S'))
cameraNode_->Translate(Vector3(0,0,-1)*MOVE_SPEED*timeStep);
if(input->GetKeyDown('A'))
cameraNode_->Translate(Vector3(-1,0,0)*MOVE_SPEED*timeStep);
if(input->GetKeyDown('D'))
cameraNode_->Translate(Vector3( 1,0,0)*MOVE_SPEED*timeStep);
if(!GetSubsystem<Input>()->IsMouseVisible())
{
IntVector2 mouseMove=input->GetMouseMove();
if(mouseMove.x_>-2000000000&&mouseMove.y_>-2000000000)
{
static float yaw_=0;
static float pitch_=0;
yaw_+=MOUSE_SENSITIVITY*mouseMove.x_;
pitch_+=MOUSE_SENSITIVITY*mouseMove.y_;
pitch_=Clamp(pitch_,-90.0f,90.0f);
// Reset rotation and set yaw and pitch again
cameraNode_->SetDirection(Vector3::FORWARD);
cameraNode_->Yaw(yaw_);
cameraNode_->Pitch(pitch_);
}
}
}
void HandleKeyDown(StringHash eventType,VariantMap& eventData)
{
using namespace KeyDown;
int key=eventData[P_KEY].GetInt();
if(key==KEY_TAB)
{
GetSubsystem<Input>()->SetMouseVisible(!GetSubsystem<Input>()->IsMouseVisible());
GetSubsystem<Input>()->SetMouseGrabbed(!GetSubsystem<Input>()->IsMouseGrabbed());
}
else if(key==KEY_ESCAPE)
engine_->Exit();
else if(key==KEY_T)
camera_->SetFillMode(camera_->GetFillMode()==FILL_WIREFRAME?FILL_SOLID:FILL_WIREFRAME);
}
};
URHO3D_DEFINE_APPLICATION_MAIN(ProblemMCVE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment