Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support instance sensor (it can be used in viewer.cpp directly) #2080

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

cmake_minimum_required(VERSION 3.12)

set(CMAKE_CUDA_COMPILER "/usr/local/cuda/bin/nvcc")
Jianghanxiao marked this conversation as resolved.
Show resolved Hide resolved

option(BUILD_WITH_CUDA "Build Habitat-Sim with CUDA features enabled -- Requires CUDA"
OFF
)
Expand Down
2 changes: 1 addition & 1 deletion src/esp/gfx/BackgroundRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ int BackgroundRenderer::threadRender() {
if (sensorType == sensor::SensorType::Depth)
sensor.renderTarget().readFrameDepth(view);

if (sensorType == sensor::SensorType::Semantic)
if (sensorType == sensor::SensorType::Semantic || sensorType == sensor::SensorType::Instance)
sensor.renderTarget().readFrameObjectId(view);
}

Expand Down
11 changes: 10 additions & 1 deletion src/esp/gfx/PbrDrawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,23 @@ void PbrDrawable::draw(const Mn::Matrix4& transformationMatrix,
Mn::GL::Renderer::setFrontFace(Mn::GL::Renderer::FrontFace::ClockWise);
}

// Pick the semantic id or the instance id based on the camera type
int specificID = 0;
if(static_cast<RenderCamera&>(camera).getIsInstanceId()) {
specificID = node_.getInstanceId();
}
else {
specificID = node_.getSemanticId();
}

(*shader_)
// e.g., semantic mesh has its own per vertex annotation, which has
// been uploaded to GPU so simply pass 0 to the uniform "objectId" in
// the fragment shader
.setObjectId(
static_cast<RenderCamera&>(camera).useDrawableIds()
? drawableId_
: (materialData_->perVertexObjectId ? 0 : node_.getSemanticId()))
: (materialData_->perVertexObjectId ? 0 : specificID))
.setProjectionMatrix(camera.projectionMatrix())
.setViewMatrix(camera.cameraMatrix())
.setModelMatrix(modelMatrix) // NOT modelview matrix!
Expand Down
6 changes: 6 additions & 0 deletions src/esp/gfx/RenderCamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ class RenderCamera : public MagnumCamera {
size_t filterTransforms(DrawableTransforms& drawableTransforms,
Flags flags = {});


void setIsInstanceId(bool isInstanceId) { isInstanceId_ = isInstanceId; }

bool getIsInstanceId() const { return isInstanceId_; }

/**
* @brief if the "immediate" following rendering pass is to use drawable ids
* as the object ids.
Expand Down Expand Up @@ -254,6 +259,7 @@ class RenderCamera : public MagnumCamera {
Mn::Matrix4 invertedProjectionMatrix;
size_t previousNumVisibleDrawables_ = 0;
bool useDrawableIds_ = false;
bool isInstanceId_ = false;
ESP_SMART_POINTERS(RenderCamera)
};

Expand Down
16 changes: 12 additions & 4 deletions src/esp/gfx/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ struct Renderer::Impl {
void draw(sensor::VisualSensor& visualSensor, sim::Simulator& sim) {
acquireGlContext();
if (visualSensor.specification()->sensorType ==
sensor::SensorType::Semantic) {
sensor::SensorType::Semantic || visualSensor.specification()->sensorType ==
sensor::SensorType::Instance) {
ESP_CHECK(sim.semanticSceneGraphExists(),
"Renderer::Impl::draw(): SemanticSensor observation requested "
"but no SemanticSceneGraph is loaded");
Expand All @@ -101,7 +102,7 @@ struct Renderer::Impl {
acquireGlContext();
sensor::SensorType& type = visualSensor.specification()->sensorType;
if (type == sensor::SensorType::Depth ||
type == sensor::SensorType::Semantic) {
type == sensor::SensorType::Semantic || type == sensor::SensorType::Instance) {
Mn::GL::Renderer::disable(Mn::GL::Renderer::Feature::DepthTest);
gfx::RenderTarget& tgt = visualSensor.renderTarget();
if (!mesh_) {
Expand All @@ -112,7 +113,7 @@ struct Renderer::Impl {
esp::gfx::Renderer::Impl::RendererShaderType rendererShaderType =
esp::gfx::Renderer::Impl::RendererShaderType::DepthTextureVisualizer;

if (type == sensor::SensorType::Semantic) {
if (type == sensor::SensorType::Semantic || type == sensor::SensorType::Instance) {
rendererShaderType =
gfx::Renderer::Impl::RendererShaderType::ObjectIdTextureVisualizer;
}
Expand Down Expand Up @@ -160,7 +161,7 @@ struct Renderer::Impl {
shader->bindDepthTexture(tgt.getDepthTexture());
#endif
shader->setDepthUnprojection(*visualSensor.depthUnprojection());
} else if (type == sensor::SensorType::Semantic) {
} else if (type == sensor::SensorType::Semantic || type == sensor::SensorType::Instance) {
shader->bindObjectIdTexture(tgt.getObjectIdTexture());
}
if ((colorMapOffset >= 0) && (colorMapScale >= 0)) {
Expand Down Expand Up @@ -365,6 +366,13 @@ struct Renderer::Impl {
renderTargetFlags |= RenderTarget::Flag::ObjectIdAttachment;
break;

case sensor::SensorType::Instance:
if (bindingFlags & Flag::VisualizeTexture) {
renderTargetFlags |= RenderTarget::Flag::RgbaAttachment;
}
renderTargetFlags |= RenderTarget::Flag::ObjectIdAttachment;
break;

default:
// I need this default, since sensor type list is long, and without
// default clang-tidy will complain
Expand Down
4 changes: 4 additions & 0 deletions src/esp/metadata/attributes/ObjectAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ class ObjectAttributes : public AbstractObjectAttributes {

uint32_t getSemanticId() const { return get<int>("semantic_id"); }

void setInstanceId(int instance_id) { set("instance_id", instance_id); }

uint32_t getInstanceId() const { return get<int>("instance_id"); }

protected:
/**
* @brief Write object-specific values to json object
Expand Down
4 changes: 4 additions & 0 deletions src/esp/physics/PhysicsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ int PhysicsManager::addObjectInstance(
<< "as specified in object instance attributes.";
return 0;
}

// Set the instance id of the object
objAttributes->setInstanceId(objInstAttributes->getID());

// check if an object is being set to be not visible for a particular
// instance.
int visSet = objInstAttributes->getIsInstanceVisible();
Expand Down
16 changes: 16 additions & 0 deletions src/esp/physics/RigidBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,22 @@ class RigidBase : public esp::physics::PhysicsObjectBase {
}
}

/**
* @brief Get the Instance ID for this object.
*/
int getInstanceId() const { return visualNode_->getInstanceId(); }

/**
* @brief Set the @ref esp::scene::SceneNode::InstanceId_ for all visual nodes
* belonging to the object.
* @param InstanceId The desired Instance id for the object.
*/
void setInstanceId(uint32_t instanceId) {
for (auto* node : visualNodes_) {
node->setInstanceId(instanceId);
}
}

/**
* @brief Get pointers to this rigid's visual SceneNodes.
* @return vector of pointers to the rigid's visual scene nodes.
Expand Down
1 change: 1 addition & 0 deletions src/esp/physics/RigidObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ bool RigidObject::finalizeObject() {

// set the visualization semantic id
setSemanticId(ObjectAttributes->getSemanticId());
setInstanceId(ObjectAttributes->getInstanceId());

// finish object by instancing any dynamics library-specific code required
return finalizeObject_LibSpecific();
Expand Down
7 changes: 7 additions & 0 deletions src/esp/scene/SceneNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ class SceneNode : public MagnumObject,
//! Sets node semanticId
virtual void setSemanticId(int semanticId) { semanticId_ = semanticId; }

//! Returns node instanceId
virtual int getInstanceId() const { return instanceId_; }

//! Sets node instanceId
virtual void setInstanceId(int instanceId) { instanceId_ = instanceId; }

Magnum::Vector3 absoluteTranslation() const;

Magnum::Vector3 absoluteTranslation();
Expand Down Expand Up @@ -234,6 +240,7 @@ class SceneNode : public MagnumObject,
//! The semantic category of this node. Used to render attached Drawables with
//! Semantic sensor when no perVertexObjectIds are present.
uint32_t semanticId_ = 0;
uint32_t instanceId_ = 0;

//! the local bounding box for meshes stored at this node
Magnum::Range3D meshBB_;
Expand Down
7 changes: 6 additions & 1 deletion src/esp/sensor/CameraSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,12 @@ bool CameraSensor::drawObservation(sim::Simulator& sim) {
flags |= gfx::RenderCamera::Flag::FrustumCulling;
}

if (cameraSensorSpec_->sensorType == SensorType::Semantic) {
if (cameraSensorSpec_->sensorType == SensorType::Semantic || cameraSensorSpec_->sensorType == SensorType::Instance) {
if (cameraSensorSpec_->sensorType == SensorType::Semantic) {
renderCamera_->setIsInstanceId(false);
} else {
renderCamera_->setIsInstanceId(true);
}
// TODO: check sim has semantic scene graph
bool twoSceneGraphs =
(&sim.getActiveSemanticSceneGraph() != &sim.getActiveSceneGraph());
Expand Down
11 changes: 9 additions & 2 deletions src/esp/sensor/CubeMapSensorBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ CubeMapSensorBase::CubeMapSensorBase(scene::SceneNode& cameraNode,
case SensorType::Semantic:
cubeMapFlags |= gfx::CubeMap::Flag::ObjectIdTexture;
break;
case SensorType::Instance:
cubeMapFlags |= gfx::CubeMap::Flag::ObjectIdTexture;
break;
default:
CORRADE_INTERNAL_ASSERT_UNREACHABLE();
break;
Expand All @@ -80,6 +83,9 @@ CubeMapSensorBase::CubeMapSensorBase(scene::SceneNode& cameraNode,
case SensorType::Semantic:
cubeMapShaderBaseFlags_ |= gfx::CubeMapShaderBase::Flag::ObjectIdTexture;
break;
case SensorType::Instance:
cubeMapShaderBaseFlags_ |= gfx::CubeMapShaderBase::Flag::ObjectIdTexture;
break;
// sensor type list is too long, have to use default
default:
CORRADE_INTERNAL_ASSERT_UNREACHABLE();
Expand Down Expand Up @@ -121,7 +127,7 @@ bool CubeMapSensorBase::renderToCubemapTexture(sim::Simulator& sim) {

// generate the cubemap texture
const char* defaultDrawableGroupName = "";
if (cubeMapSensorBaseSpec_->sensorType == SensorType::Semantic) {
if (cubeMapSensorBaseSpec_->sensorType == SensorType::Semantic || cubeMapSensorBaseSpec_->sensorType == SensorType::Instance) {
bool twoSceneGraphs =
(&sim.getActiveSemanticSceneGraph() != &sim.getActiveSceneGraph());

Expand Down Expand Up @@ -164,7 +170,8 @@ void CubeMapSensorBase::drawWith(gfx::CubeMapShaderBase& shader) {
shader.bindDepthTexture(
cubeMap_->getTexture(gfx::CubeMap::TextureType::Depth));
}
if (cubeMapSensorBaseSpec_->sensorType == SensorType::Semantic) {
if (cubeMapSensorBaseSpec_->sensorType == SensorType::Semantic ||
cubeMapSensorBaseSpec_->sensorType == SensorType::Instance) {
shader.bindObjectIdTexture(
cubeMap_->getTexture(gfx::CubeMap::TextureType::ObjectId));
}
Expand Down
1 change: 1 addition & 0 deletions src/esp/sensor/Sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum class SensorType : int32_t {
Tensor,
Text,
Audio,
Instance,
SensorTypeCount, // add new type above this term!!
};

Expand Down
10 changes: 5 additions & 5 deletions src/esp/sensor/VisualSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void VisualSensorSpec::sanityCheck() const {
SensorSpec::sanityCheck();
bool isVisualSensor =
(sensorType == SensorType::Color || sensorType == SensorType::Depth ||
sensorType == SensorType::Normal || sensorType == SensorType::Semantic);
sensorType == SensorType::Normal || sensorType == SensorType::Semantic || sensorType == SensorType::Instance);
CORRADE_ASSERT(
isVisualSensor,
"VisualSensorSpec::sanityCheck(): sensorType must be Color, Depth, "
Expand Down Expand Up @@ -90,7 +90,7 @@ bool VisualSensor::getObservationSpace(ObservationSpace& space) {
static_cast<size_t>(visualSensorSpec_->resolution[1]),
static_cast<size_t>(visualSensorSpec_->channels)};
space.dataType = core::DataType::DT_UINT8;
if (visualSensorSpec_->sensorType == SensorType::Semantic) {
if (visualSensorSpec_->sensorType == SensorType::Semantic or visualSensorSpec_->sensorType == SensorType::Instance) {
space.dataType = core::DataType::DT_UINT32;
} else if (visualSensorSpec_->sensorType == SensorType::Depth) {
space.dataType = core::DataType::DT_FLOAT;
Expand All @@ -110,7 +110,7 @@ void VisualSensor::readObservation(Observation& obs) {

// TODO: have different classes for the different types of sensors
// TODO: do we need to flip axis?
if (visualSensorSpec_->sensorType == SensorType::Semantic) {
if (visualSensorSpec_->sensorType == SensorType::Semantic or visualSensorSpec_->sensorType == SensorType::Instance) {
renderTarget().readFrameObjectId(Magnum::MutableImageView2D{
Magnum::PixelFormat::R32UI, renderTarget().framebufferSize(),
obs.buffer->data});
Expand Down Expand Up @@ -153,7 +153,7 @@ VisualSensor::MoveSemanticSensorNodeHelper::MoveSemanticSensorNodeHelper(
sim::Simulator& sim)
: visualSensor_(visualSensor), sim_(sim) {
CORRADE_INTERNAL_ASSERT(visualSensor_.specification()->sensorType ==
SensorType::Semantic);
SensorType::Semantic || visualSensor_.specification()->sensorType == SensorType::Instance);
scene::SceneNode& node = visualSensor_.node();
CORRADE_ASSERT(
!scene::SceneGraph::isRootNode(node),
Expand Down Expand Up @@ -189,7 +189,7 @@ VisualSensor::MoveSemanticSensorNodeHelper::MoveSemanticSensorNodeHelper(

VisualSensor::MoveSemanticSensorNodeHelper::~MoveSemanticSensorNodeHelper() {
CORRADE_INTERNAL_ASSERT(visualSensor_.specification()->sensorType ==
SensorType::Semantic);
SensorType::Semantic or visualSensor_.specification()->sensorType == SensorType::Instance);

scene::SceneNode& node = visualSensor_.node();
CORRADE_ASSERT(
Expand Down