mirror of
https://github.com/openglobus/openglobus.git
synced 2025-12-08 19:25:27 +00:00
buffer slice fix, cleanup
This commit is contained in:
parent
50a1a6141d
commit
18404fe1ca
@ -28,7 +28,7 @@ import {
|
||||
RenderNode,
|
||||
EntityCollection,
|
||||
scene,
|
||||
Gltf
|
||||
Gltf,
|
||||
} from "../../lib/og.es.js";
|
||||
|
||||
let renderer = new Renderer("frame", {
|
||||
@ -43,211 +43,36 @@ class MyScene extends RenderNode {
|
||||
}
|
||||
|
||||
init() {
|
||||
const baseObj = Object3d.createCube(0.4, 2, 0.4).translate(new Vec3(0, 1, 0)).setMaterial({
|
||||
ambient: "#882a2a",
|
||||
diffuse: "#fb3434",
|
||||
shininess: 1
|
||||
});
|
||||
|
||||
const frustumObj = Object3d.createFrustum(3, 2, 1).setMaterial({
|
||||
ambient: "#236028",
|
||||
diffuse: "#1cdd23",
|
||||
shininess: 1
|
||||
});
|
||||
|
||||
const cylinderObj = Object3d.createCylinder(1, 0, 1)
|
||||
.applyMat4(new Mat4().setRotation(new Vec3(1, 0, 0), (90 * Math.PI) / 180))
|
||||
.setMaterial({
|
||||
ambient: "#773381",
|
||||
diffuse: "#ef00ff",
|
||||
shininess: 1
|
||||
});
|
||||
|
||||
let parentEntity = new Entity({
|
||||
cartesian: new Vec3(0, 0, 0),
|
||||
independentPicking: true
|
||||
// geoObject: {
|
||||
// color: "rgb(90,90,90)",
|
||||
// scale: 1,
|
||||
// instanced: true,
|
||||
// tag: `baseObj`,
|
||||
// object3d: baseObj
|
||||
// }
|
||||
});
|
||||
|
||||
let childEntity = new Entity({
|
||||
cartesian: new Vec3(0, 1, 0),
|
||||
independentPicking: true,
|
||||
relativePosition: true,
|
||||
geoObject: {
|
||||
color: "rgb(90,90,90)",
|
||||
instanced: true,
|
||||
tag: `frustumObj`,
|
||||
object3d: frustumObj
|
||||
}
|
||||
});
|
||||
|
||||
let childChildEntity = new Entity({
|
||||
cartesian: new Vec3(0, 3, -1),
|
||||
independentPicking: true,
|
||||
relativePosition: true,
|
||||
geoObject: {
|
||||
color: "rgb(90,90,90)",
|
||||
instanced: true,
|
||||
tag: `cylinderObj`,
|
||||
object3d: cylinderObj
|
||||
}
|
||||
});
|
||||
|
||||
childEntity.appendChild(childChildEntity);
|
||||
parentEntity.appendChild(childEntity);
|
||||
|
||||
let collection = new EntityCollection({
|
||||
entities: [parentEntity]
|
||||
entities: []
|
||||
});
|
||||
|
||||
collection.addTo(this);
|
||||
|
||||
this.renderer.activeCamera.set(new Vec3(-4, 21, 23), new Vec3(1, 0, 0));
|
||||
this.renderer.activeCamera.set(new Vec3(20, 21, 23), new Vec3(10, 0, 0));
|
||||
|
||||
this.renderer.activeCamera.update();
|
||||
DracoDecoderModule().then((decoderModule) => {
|
||||
Gltf.connectDracoDecoderModule(decoderModule);
|
||||
Gltf.loadGlb("./maxwell_the_cat.glb").then((gltf) => {
|
||||
// const models = gltf.getObjects3d();
|
||||
const entities = gltf.toEntities();
|
||||
console.log("entities", entities);
|
||||
const cat = entities[0];
|
||||
cat.setScale(0.1);
|
||||
childChildEntity.appendChild(entities[0]);
|
||||
// childChildEntity.appendChild(
|
||||
// new Entity({
|
||||
// cartesian: new Vec3(0, 3, -1),
|
||||
// independentPicking: true,
|
||||
// relativePosition: true,
|
||||
// geoObject: {
|
||||
// color: "rgb(90,90,90)",
|
||||
// instanced: true,
|
||||
// tag: `circleObj`,
|
||||
// object3d: models[0]
|
||||
// }
|
||||
// })
|
||||
// );
|
||||
cat.setScale(0.5);
|
||||
cat.setPitch(-90 * (Math.PI / 180));
|
||||
collection.add(cat);
|
||||
this.renderer.activeCamera.update();
|
||||
});
|
||||
});
|
||||
|
||||
// Gltf.loadGlb("./CesiumMilkTruck.glb").then((gltf) => {
|
||||
// const entity = gltf.toEntities()[0];
|
||||
// entity.setScale(1);
|
||||
// console.log('truck entity', entity);
|
||||
// childChildEntity.appendChild(entity);
|
||||
// this.renderer.activeCamera.update();
|
||||
// });
|
||||
Gltf.loadGlb("./f22.glb").then((gltf) => {
|
||||
const entity = gltf.toEntities()[0];
|
||||
entity.setScale(1);
|
||||
entity.setCartesian(20, 5, 0);
|
||||
entity.setPitch(90 * (Math.PI / 180));
|
||||
collection.add(entity);
|
||||
this.renderer.activeCamera.update();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
renderer.addNodes([new scene.Axes(), new MyScene()]);
|
||||
|
||||
async function loadGLB(url) {
|
||||
const response = await fetch(url);
|
||||
const buffer = response.arrayBuffer();
|
||||
return await buffer;
|
||||
}
|
||||
|
||||
function parseGLB(arrayBuffer) {
|
||||
const dv = new DataView(arrayBuffer);
|
||||
const magic = dv.getUint32(0, true);
|
||||
if (magic !== 0x46546c67) throw new Error("Not a valid GLB");
|
||||
|
||||
const jsonChunkLength = dv.getUint32(12, true);
|
||||
const jsonChunkStart = 20;
|
||||
const jsonChunk = new TextDecoder().decode(
|
||||
new Uint8Array(arrayBuffer, jsonChunkStart, jsonChunkLength)
|
||||
);
|
||||
const gltf = JSON.parse(jsonChunk);
|
||||
const chunks = [];
|
||||
const binChunkStart = 20 + jsonChunkLength;
|
||||
for (let i = 0; i < gltf.bufferViews.length; i++) {
|
||||
const bufferView = gltf.bufferViews[i];
|
||||
const offset = i + 1;
|
||||
const start = binChunkStart + 8 * offset + bufferView.byteOffset;
|
||||
chunks.push(arrayBuffer.slice(start, start + bufferView.byteLength));
|
||||
}
|
||||
|
||||
return { gltf, chunks };
|
||||
}
|
||||
|
||||
function getDracoCompressedAccessor(gltf) {
|
||||
for (const mesh of gltf.meshes) {
|
||||
for (const primitive of mesh.primitives) {
|
||||
if (primitive.extensions && primitive.extensions["KHR_draco_mesh_compression"]) {
|
||||
return primitive.extensions["KHR_draco_mesh_compression"];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function decodeDraco(decoderModule, binChunk, gltf) {
|
||||
console.log(gltf);
|
||||
const byteOffset = 0; // optional: read from bufferView
|
||||
const dracoBufferView = new Uint8Array(binChunk, byteOffset); // if bufferView.byteOffset is available, use it
|
||||
const decoder = new decoderModule.Decoder();
|
||||
const buffer = new decoderModule.DecoderBuffer();
|
||||
buffer.Init(dracoBufferView, dracoBufferView.byteLength);
|
||||
|
||||
const geometryType = decoder.GetEncodedGeometryType(buffer);
|
||||
if (geometryType !== decoderModule.TRIANGULAR_MESH) {
|
||||
throw new Error("Not a mesh");
|
||||
}
|
||||
|
||||
const mesh = new decoderModule.Mesh();
|
||||
const status = decoder.DecodeBufferToMesh(buffer, mesh);
|
||||
if (!status.ok() || mesh.ptr === 0) {
|
||||
console.log(status.error_msg());
|
||||
throw new Error("Failed to decode Draco mesh");
|
||||
}
|
||||
|
||||
const posAttrId = decoder.GetAttributeId(mesh, decoderModule.POSITION);
|
||||
const posAttr = decoder.GetAttribute(mesh, posAttrId);
|
||||
const numPoints = mesh.num_points();
|
||||
|
||||
const pos = new decoderModule.DracoFloat32Array();
|
||||
decoder.GetAttributeFloatForAllPoints(mesh, posAttr, pos);
|
||||
|
||||
const positions = new Float32Array(numPoints * 3);
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
positions[i] = pos.GetValue(i);
|
||||
}
|
||||
|
||||
decoderModule.destroy(pos);
|
||||
decoderModule.destroy(mesh);
|
||||
decoderModule.destroy(decoder);
|
||||
decoderModule.destroy(buffer);
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
const test = async () => {
|
||||
// const arrayBuffer = await loadGLB("./CesiumMilkTruck.glb");
|
||||
// const { gltf, chunks } = parseGLB(arrayBuffer);
|
||||
// // const dracoExt = getDracoCompressedAccessor(gltf);
|
||||
// console.log(gltf, chunks);
|
||||
// // eslint-disable-next-line no-undef
|
||||
// const decoderModule = await DracoDecoderModule();
|
||||
// await decoderModule.ready;
|
||||
// const positions = decodeDraco(decoderModule, chunks[2], gltf);
|
||||
// console.log(positions);
|
||||
// const buffer = new decoderModule.DecoderBuffer();
|
||||
// buffer.Init(cat, cat.length);
|
||||
// const decoder = new decoderModule.Decoder();
|
||||
// const geometryType = decoder.GetEncodedGeometryType(buffer);
|
||||
// console.log(decoderModule, geometryType);
|
||||
// const gltf = await Gltf.loadGlb("./CesiumMilkTruck.glb");
|
||||
// const objects = gltf.getObjects3d();
|
||||
// console.log(objects);
|
||||
// await Gltf.loadGlb("./maxwell_the_cat.glb");
|
||||
};
|
||||
|
||||
test();
|
||||
|
||||
BIN
sandbox/modelLoad/f22.glb
Normal file
BIN
sandbox/modelLoad/f22.glb
Normal file
Binary file not shown.
@ -29,7 +29,6 @@ export class Gltf {
|
||||
if (this.dracoDecoderModule !== null) {
|
||||
await this.dracoDecoderModule.ready;
|
||||
}
|
||||
console.log("load glb", data);
|
||||
return new Gltf(data);
|
||||
}
|
||||
|
||||
@ -371,7 +370,6 @@ export class Gltf {
|
||||
}
|
||||
|
||||
private static toObject3d(primitive: Primitive): Object3d {
|
||||
console.log('building object3d', primitive);
|
||||
return new Object3d({
|
||||
name: primitive.name,
|
||||
vertices: Array.from(primitive.vertices as Float32Array),
|
||||
@ -393,22 +391,25 @@ export class Gltf {
|
||||
private static access(accessor: Accessor, gltf: GltfData): ArrayBufferLike {
|
||||
const bufferView = gltf.gltf.bufferViews[accessor.bufferView];
|
||||
const arrbuff = gltf.bin[bufferView.buffer];
|
||||
const offset = bufferView.byteOffset || 0;
|
||||
let offset = bufferView.byteOffset || 0;
|
||||
if (accessor.byteOffset !== undefined) {
|
||||
offset += accessor.byteOffset;
|
||||
}
|
||||
const dv = arrbuff.slice(offset, offset + bufferView.byteLength);
|
||||
switch (accessor.type) {
|
||||
case AccessorDataType.scalar:
|
||||
return this.getTensor(dv, accessor, 1);
|
||||
return this.getTensor(dv, accessor, 1, bufferView.byteStride);
|
||||
case AccessorDataType.vec2:
|
||||
return this.getTensor(dv, accessor, 2);
|
||||
return this.getTensor(dv, accessor, 2, bufferView.byteStride);
|
||||
case AccessorDataType.vec3:
|
||||
return this.getTensor(dv, accessor, 3);
|
||||
return this.getTensor(dv, accessor, 3, bufferView.byteStride);
|
||||
case AccessorDataType.vec4:
|
||||
case AccessorDataType.mat2:
|
||||
return this.getTensor(dv, accessor, 4);
|
||||
return this.getTensor(dv, accessor, 4, bufferView.byteStride);
|
||||
case AccessorDataType.mat3:
|
||||
return this.getTensor(dv, accessor, 9);
|
||||
return this.getTensor(dv, accessor, 9, bufferView.byteStride);
|
||||
case AccessorDataType.mat4:
|
||||
return this.getTensor(dv, accessor, 16);
|
||||
return this.getTensor(dv, accessor, 16, bufferView.byteStride);
|
||||
default:
|
||||
throw new Error("Unknown accessor type");
|
||||
}
|
||||
@ -417,7 +418,8 @@ export class Gltf {
|
||||
private static getTensor(
|
||||
buffer: ArrayBuffer,
|
||||
accessor: Accessor,
|
||||
numOfComponents: number
|
||||
numOfComponents: number,
|
||||
byteStride?: number // TODO: implement byteStride handling if data not tightly packed
|
||||
): ArrayBufferLike {
|
||||
if (accessor.componentType === AccessorComponentType.ushort) {
|
||||
return new Uint16Array(buffer, 0, accessor.count * numOfComponents);
|
||||
|
||||
@ -111,6 +111,7 @@ export enum MimeType {
|
||||
|
||||
export interface Accessor {
|
||||
bufferView: number;
|
||||
byteOffset?: number;
|
||||
componentType: AccessorComponentType;
|
||||
count: number;
|
||||
type: AccessorDataType;
|
||||
@ -123,6 +124,7 @@ export interface BufferView {
|
||||
byteLength: number;
|
||||
byteOffset: number;
|
||||
target?: BufferViewTarget;
|
||||
byteStride?: number;
|
||||
}
|
||||
|
||||
export enum BufferViewTarget {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user