11import {
22 LineType ,
3+ ModelPrimitive ,
34 SceneEntityDeletionType ,
45 SceneUpdate ,
56 TextPrimitive ,
@@ -39,7 +40,11 @@ import {
3940import { ExtensionContext , Immutable , MessageEvent , PanelSettings } from "@lichtblick/suite" ;
4041import { eulerToQuaternion , quaternionMultiplication } from "@utils/geometry" ;
4142import { ColorCode } from "@utils/helper" ;
42- import { objectToCubePrimitive , pointListToTriangleListPrimitive } from "@utils/marker" ;
43+ import {
44+ objectToCubePrimitive ,
45+ pointListToTriangleListPrimitive ,
46+ objectToModelPrimitive ,
47+ } from "@utils/marker" ;
4348import { PartialSceneEntity , generateSceneEntityId } from "@utils/scene" ;
4449import { DeepPartial , DeepRequired } from "ts-essentials" ;
4550
@@ -82,15 +87,35 @@ type Config = {
8287 showAxes : boolean ;
8388 showPhysicalLanes : boolean ;
8489 showLogicalLanes : boolean ;
90+ showBoundingBox : boolean ;
91+ show3dModels : boolean ;
8592} ;
8693
94+ function createModelPrimitive ( movingObject : DeepRequired < MovingObject > ) : ModelPrimitive {
95+ const model_primitive = objectToModelPrimitive (
96+ movingObject . base . position . x ,
97+ movingObject . base . position . y ,
98+ movingObject . base . position . z - movingObject . base . dimension . height / 2 ,
99+ movingObject . base . orientation . roll ,
100+ movingObject . base . orientation . pitch ,
101+ movingObject . base . orientation . yaw ,
102+ 1 ,
103+ 1 ,
104+ 1 ,
105+ { r : 0 , g : 0 , b : 0 , a : 0 } ,
106+ "file://" + movingObject . model_reference , // Should be absolute path
107+ ) ;
108+ return model_primitive ;
109+ }
110+
87111function buildObjectEntity (
88112 osiObject : DeepRequired < MovingObject > | DeepRequired < StationaryObject > ,
89113 color : Color ,
90114 id_prefix : string ,
91115 frame_id : string ,
92116 time : Time ,
93117 config : Config | undefined ,
118+ modelCache : Map < string , ModelPrimitive > ,
94119 metadata ?: KeyValuePair [ ] ,
95120) : PartialSceneEntity {
96121 const cube = objectToCubePrimitive (
@@ -148,15 +173,39 @@ function buildObjectEntity(
148173 ] ;
149174 }
150175
176+ function getUpdatedModelPrimitives ( ) : ModelPrimitive [ ] {
177+ if ( config != null && config . show3dModels ) {
178+ const model_primitive = modelCache . get ( osiObject . model_reference ) ;
179+ if ( model_primitive == undefined ) {
180+ return [ ] ;
181+ }
182+
183+ model_primitive . pose . position . x = osiObject . base . position . x ;
184+ model_primitive . pose . position . y = osiObject . base . position . y ;
185+ model_primitive . pose . position . z =
186+ osiObject . base . position . z - osiObject . base . dimension . height / 2 ;
187+ model_primitive . pose . orientation = eulerToQuaternion (
188+ osiObject . base . orientation . roll ,
189+ osiObject . base . orientation . pitch ,
190+ osiObject . base . orientation . yaw ,
191+ ) ;
192+
193+ return [ model_primitive ] ;
194+ }
195+
196+ return [ ] ;
197+ }
198+
151199 return {
152200 timestamp : time ,
153201 frame_id,
154202 id : generateSceneEntityId ( id_prefix , osiObject . id . value ) ,
155203 lifetime : { sec : 0 , nsec : 0 } ,
156204 frame_locked : true ,
157- cubes : [ cube ] ,
205+ cubes : config != null && config . showBoundingBox ? [ cube ] : [ ] ,
158206 arrows : buildAxes ( ) ,
159207 metadata,
208+ models : getUpdatedModelPrimitives ( ) ,
160209 } ;
161210}
162211
@@ -389,6 +438,7 @@ function buildSceneEntities(
389438 osiGroundTruth : DeepRequired < GroundTruth > ,
390439 updateFlags : OSISceneEntitesUpdate ,
391440 config : Config | undefined ,
441+ modelCache : Map < string , ModelPrimitive > ,
392442) : OSISceneEntities {
393443 const time : Time = osiTimestampToTime ( osiGroundTruth . timestamp ) ;
394444
@@ -403,6 +453,12 @@ function buildSceneEntities(
403453 value : MovingObject_Type [ obj . type ] ,
404454 } ,
405455 ] ;
456+
457+ const modelPathKey = obj . model_reference ;
458+ if ( ! modelCache . has ( modelPathKey ) && modelPathKey . startsWith ( "/" ) ) {
459+ modelCache . set ( modelPathKey , createModelPrimitive ( obj ) ) ;
460+ }
461+
406462 if ( obj . id . value === osiGroundTruth . host_vehicle_id . value ) {
407463 metadata = [ ...metadata , ...buildVehicleMetadata ( obj . vehicle_classification ) ] ;
408464 entity = buildObjectEntity (
@@ -412,6 +468,7 @@ function buildSceneEntities(
412468 ROOT_FRAME ,
413469 time ,
414470 config ,
471+ modelCache ,
415472 metadata ,
416473 ) ;
417474 } else {
@@ -429,6 +486,7 @@ function buildSceneEntities(
429486 ROOT_FRAME ,
430487 time ,
431488 config ,
489+ modelCache ,
432490 metadata ,
433491 ) ;
434492 }
@@ -449,6 +507,7 @@ function buildSceneEntities(
449507 ROOT_FRAME ,
450508 time ,
451509 config ,
510+ modelCache ,
452511 metadata ,
453512 ) ;
454513 } ) ;
@@ -761,6 +820,7 @@ export function activate(extensionContext: ExtensionContext): void {
761820 let groundTruthFrameCache = new WeakMap < GroundTruth , PartialSceneEntity [ ] > ( ) ; // Weakly stores scene entities for each individual OSI ground truth frame
762821 const laneBoundaryCache = new Map < string , PartialSceneEntity [ ] > ( ) ; // Note: A maximum of one entry is kept in this cache.
763822 const laneCache = new Map < string , PartialSceneEntity [ ] > ( ) ; // Note: A maximum of one entry is kept in this cache.
823+ const modelCache = new Map < string , ModelPrimitive > ( ) ; // This cache will hold the first time loaded models with model path key
764824
765825 const state = {
766826 previousMovingObjectIds : new Set < number > ( ) ,
@@ -912,7 +972,7 @@ export function activate(extensionContext: ExtensionContext): void {
912972 logicalLaneBoundaries,
913973 lanes,
914974 logicalLanes,
915- } = buildSceneEntities ( osiGroundTruthReq , updateFlags , config ) ;
975+ } = buildSceneEntities ( osiGroundTruthReq , updateFlags , config , modelCache ) ;
916976
917977 // Concatenate newly generated and cached scene entities
918978 sceneEntities = [
@@ -1078,6 +1138,16 @@ export function activate(extensionContext: ExtensionContext): void {
10781138 input : "boolean" ,
10791139 value : config ?. showLogicalLanes ,
10801140 } ,
1141+ showBoundingBox : {
1142+ label : "Show Bounding Box" ,
1143+ input : "boolean" ,
1144+ value : config ?. showBoundingBox ,
1145+ } ,
1146+ show3dModels : {
1147+ label : "Show 3D Models" ,
1148+ input : "boolean" ,
1149+ value : config ?. show3dModels ,
1150+ } ,
10811151 } ,
10821152 } ) ,
10831153 handler : ( action , config : Config | undefined ) => {
@@ -1096,12 +1166,20 @@ export function activate(extensionContext: ExtensionContext): void {
10961166 if ( action . action === "update" && action . payload . path [ 2 ] === "showLogicalLanes" ) {
10971167 config . showLogicalLanes = action . payload . value as boolean ;
10981168 }
1169+ if ( action . action === "update" && action . payload . path [ 2 ] === "showBoundingBox" ) {
1170+ config . showBoundingBox = action . payload . value as boolean ;
1171+ }
1172+ if ( action . action === "update" && action . payload . path [ 2 ] === "show3dModels" ) {
1173+ config . show3dModels = action . payload . value as boolean ;
1174+ }
10991175 } ,
11001176 defaultConfig : {
11011177 caching : true ,
11021178 showAxes : true ,
11031179 showPhysicalLanes : true ,
11041180 showLogicalLanes : false ,
1181+ showBoundingBox : true ,
1182+ show3dModels : false ,
11051183 } ,
11061184 } ) ,
11071185 } ,
0 commit comments