-
Notifications
You must be signed in to change notification settings - Fork 31
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
How to access vertex of geometry? #25
Comments
As GLTFKit2 is a fairly low-level framework, this is tedious but ultimately straightforward. One approach is to declare an Objective-C category on the @interface GLTFPrimitive (VertexPositionAccess)
- (NSData *_Nullable)copyPackedVertexPositions;
@end which could be implemented as follows @implementation GLTFPrimitive (VertexPositionAccess)
- (NSData *)copyPackedVertexPositions {
GLTFAccessor *positionAccessor = self.attributes[GLTFAttributeSemanticPosition];
if (positionAccessor == nil) {
return nil; // No position data, because the primitive didn't contain a position accessor
}
const void *sourceBufferBase = positionAccessor.bufferView.buffer.data.bytes;
const void *sourceBase = sourceBufferBase + positionAccessor.offset + positionAccessor.bufferView.offset;
if (sourceBase == NULL) {
return nil; // No position data, because buffer view or buffer is NULL, or because the buffer contains no data
}
NSInteger vertexCount = positionAccessor.count;
NSInteger destinationStride = sizeof(float) * 3;
NSInteger bufferLength = destinationStride * vertexCount;
NSInteger sourceStride = positionAccessor.bufferView.stride;
if (sourceStride == 0) {
sourceStride = destinationStride;
}
if (sourceStride == destinationStride) {
// Existing data is already packed; just return a data object that acts as a view on it
return [NSData dataWithBytesNoCopy:(void *)sourceBase length:bufferLength freeWhenDone:NO];
} else {
// Existing data is *not* packed; we need to copy it element by element
void *packedBuffer = malloc(bufferLength);
for (int i = 0; i < vertexCount; ++i) {
const void *sourcePtr = sourceBase + i * sourceStride;
void *destPtr = packedBuffer + i * destinationStride;
memcpy(destPtr, sourcePtr, destinationStride);
}
return [NSData dataWithBytesNoCopy:packedBuffer length:bufferLength freeWhenDone:YES];
}
}
@end Back in Swift, assuming you have a reference to a primitive object, you could print out all of its vertices like this: let vertexCount = primitive.attributes[GLTFAttributeSemantic.position.rawValue]?.count ?? 0
if let positionData = primitive.copyPackedVertexPositions() {
positionData.withUnsafeBytes { positionPtr in
for i in 0..<vertexCount {
let position = positionPtr.baseAddress!
.advanced(by: MemoryLayout<Float>.stride * 3 * i)
.assumingMemoryBound(to: Float.self)
let x = position[0]
let y = position[1]
let z = position[2]
print("\(x) \(y) \(z)")
}
}
} If you need to iterate over triangles in indexed order instead of just the raw vertex list, you can write a similar extension to retrieve the index data from the primitive. This is slightly more complex, because indices can be 8, 16, or 32 bits each, but at least index data is guaranteed to be packed. |
If you've already converted a glTF asset to a SceneKit scene, you can instead retrieve the vertex source of an |
This issue will be automatically closed in 7 days if no further comment is received. |
Closing due to inactivity. |
Is this still the best way to get vertex position data? |
We are trying to access all vertex positions of geometry to show Highlight point on them
could you share example of how to assess geometry vertex positions
The text was updated successfully, but these errors were encountered: