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

Feature: PNTs Draco support #326

Closed
wants to merge 6 commits into from

Conversation

Gmadges
Copy link
Contributor

@Gmadges Gmadges commented Apr 27, 2023

This PR provides support for PNTs files that are using the 3DTILES_draco_point_compression extension.

It only supports Positions & Colors currently.
This seemed fine because 3DTilesRendererJS only supports those attributes currently.
It also allowed me to use the three.js DRACOLoader class which I don't think supports arbitrary Draco attributes either (I could be wrong there).

I'm not 100% happy with the way in which I inject the Draco loader (via the the .drc handler) but it seemed like the lightest touch method that vaguely makes sense.

Copy link
Contributor

@gkjohnson gkjohnson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This looks like a good thing to add.

It also allowed me to use the three.js DRACOLoader class which I don't think supports arbitrary Draco attributes either (I could be wrong there).

This is something we can clarify if we need to broaden support to other fields like NORMAL or BATCH_ID.

It only supports Positions & Colors currently.
This seemed fine because 3DTilesRendererJS only supports those attributes currently.

For now, yes - it looks like any non-glTF file formats are deprecated in the latest 1.1 spec (see #323 (comment)) so I'm no less worried about supporting these formats in a completely robust way at the moment.

I'm not 100% happy with the way in which I inject the Draco loader (via the the .drc handler) but it seemed like the lightest touch method that vaguely makes sense.

Yeah but I don't know if I like the alternatives, either, especially given the above point:

  • Specifically we could have a setDRACOLoader function on the tiles class.
  • Ask the user to provide a custom handler for ".pnts" files that already has the draco loader set the same way we do for GLTF.

If anything maybe the second option makes the most sense? Though I'm not picky here.

Comment on lines 40 to 44
for ( const [ key, value ] of Object.entries( dracoIDs ) ) {

}
attributeIDs[ DRACO_ATTRIBUTE_MAP[ key ] ] = value;

} );
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause an undefined key if a DRACO property exists that is not "RGB" or "POSITION", right?

const dracoGeometry = await this.dracoLoader
.decodeGeometry( buffer, taskConfig );

geometry.copy( dracoGeometry );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why copy instead of just using the DRACO geometry directly?


if ( geometry.attributes.color ) {

geometry.attributes.color.normalized = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the DRACO loader not set the color field to normalized correctly automatically? Is this something that should be fixed in three.js?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I'll have a look

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made an issue and PR here
unsure if this desired behaviour for everyone, but feels like it

Comment on lines 21 to 22
// hacky way of getting the draco loader from the manager
this.dracoLoader = this.manager.getHandler( 'draco.drc' );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be done in the "parse" function rather than in the constructor.

src/three/PNTSLoader.js Show resolved Hide resolved
Comment on lines +144 to +178
isDraco() {

const { extensions } = this.header;
return extensions && !! extensions[ '3DTILES_draco_point_compression' ];

}

getDracoBuffer() {

if ( ! this.isDraco() ) {

throw new Error( 'FeatureTable: Feature data is not draco encoded' );

}

const { buffer, binOffset } = this;

const { byteOffset, byteLength } = this.header.extensions[ '3DTILES_draco_point_compression' ];

return buffer.slice( binOffset + byteOffset, binOffset + byteOffset + byteLength );

}

getDracoProperties() {

if ( ! this.isDraco() ) {

throw new Error( 'FeatureTable: Feature data is not draco encoded' );

}

return this.header.extensions[ '3DTILES_draco_point_compression' ].properties;

}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ideally the FeatureTable class wouldn't have to change since this is all really just relevant to the points properties, right? Otherwise if there are other relevant compressed buffers in the FeatureTable then it might make most sense to make a derivative class that abstracts away the draco decompression and automatically decompresses the data when a user calls "getData", for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've now moved more of the logic to a PNTSFeatureTable to keep the draco related logic away from other data types.

I wasn't able to abstract it fully so that you could just use getData() as normal. This was due to the dracoLoader returning geometry not just a typed array.

@gkjohnson
Copy link
Contributor

Just published! Thanks again

@gkjohnson gkjohnson closed this May 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants