Skip to content

Commit 5bb252c

Browse files
committed
feat: add 3d model setting
1 parent 8803754 commit 5bb252c

4 files changed

Lines changed: 89 additions & 8 deletions

File tree

common/utils/marker.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,8 @@ export function objectToModelPrimitive(
692692
length: number,
693693
height: number,
694694
color: Color,
695-
data: Uint8Array,
695+
url = "",
696+
data: Uint8Array = new Uint8Array(),
696697
): ModelPrimitive {
697698
return {
698699
pose: {
@@ -710,8 +711,8 @@ export function objectToModelPrimitive(
710711
},
711712
color,
712713
override_color: false,
713-
url: "",
714+
url,
714715
media_type: "model/gltf-binary",
715-
data,
716+
data: url.length === 0 ? data : new Uint8Array(),
716717
};
717718
}

src/index.ts

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
LineType,
3+
ModelPrimitive,
34
SceneEntityDeletionType,
45
SceneUpdate,
56
TextPrimitive,
@@ -39,7 +40,11 @@ import {
3940
import { ExtensionContext, Immutable, MessageEvent, PanelSettings } from "@lichtblick/suite";
4041
import { eulerToQuaternion, quaternionMultiplication } from "@utils/geometry";
4142
import { ColorCode } from "@utils/helper";
42-
import { objectToCubePrimitive, pointListToTriangleListPrimitive } from "@utils/marker";
43+
import {
44+
objectToCubePrimitive,
45+
pointListToTriangleListPrimitive,
46+
objectToModelPrimitive,
47+
} from "@utils/marker";
4348
import { PartialSceneEntity, generateSceneEntityId } from "@utils/scene";
4449
import { 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+
87111
function 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
},

src/trafficlights/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ export const buildTrafficLightModel = (
4040
item.base.dimension.length,
4141
item.base.dimension.height,
4242
color,
43-
modelCacheMap.get(mapKey)!,
43+
"",
44+
modelCacheMap.get(mapKey),
4445
);
4546
};
4647

src/trafficsigns/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ export const buildTrafficSignModel = (
5454
item.base.dimension.length,
5555
item.base.dimension.height,
5656
{ r: 0, g: 0, b: 0, a: 0 },
57-
modelSignCacheMap[category].get(mapKey)!,
57+
"",
58+
modelSignCacheMap[category].get(mapKey),
5859
);
5960
};
6061

0 commit comments

Comments
 (0)