我在了解Scenekit几何时遇到了问题。
我有Blender的默认多维数据集,并且可以导出为collada(DAE),并且可以将其引入Scenekit中。
现在,我想查看多维数据集的顶点。在DAE中,我可以看到“ Cube-mesh-positions-array”的以下内容,
“ 1 1 -1 1 -1 -1 -1 -0.9999998 -1 -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1”
现在,我想在Scenekit中执行的操作是使用如下所示的方法将顶点取回:
SCNGeometrySource *vertexBuffer = [[cubeNode.geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticVertex] objectAtIndex:0];
如果我处理了vertexBuffer(我尝试了多种查看数据的方法),那似乎是不正确的。
有人可以解释“ SCNGeometrySourceSemanticVertex”给我什么,以及如何正确提取顶点数据吗?我想看的是:
X = "float"
Y = "float"
Z = "float"
我还在研究以下类/方法,它们看起来很有希望(这里有一些不错的数据值),但是来自gmpe的数据似乎是空的,有人能解释“ SCNGeometryElement”的数据属性包含什么吗?
SCNGeometryElement *gmpe = [theCurrentNode.geometry geometryElementAtIndex:0];
多谢您的协助,
d
最佳答案
几何源
调用geometrySourcesForSemantic:
时,将返回具有给定语义的SCNGeometrySource
对象数组(在本例中为顶点数据的源)。
可以用许多不同的方式对这些数据进行编码,并且多个源可以使用具有不同stride
和offset
的相同数据。源本身具有一堆属性,例如,您可以解码data
dataStride
dataOffset
vectorCount
componentsPerVector
bytesPerComponent
您可以使用这些元素的组合来找出data
的哪些部分要读取并在其中制成顶点。
解码
步幅告诉您要步进到下一个向量的字节数,而offset告诉您从向量的起始位置偏移了多少字节,在到达该向量的数据相关参数之前,应偏移该字节。您应该为每个向量读取的字节数是componentsPerVector * bytesPerComponent
读取单个几何源的所有顶点的代码看起来像这样
// Get the vertex sources
NSArray *vertexSources = [geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticVertex];
// Get the first source
SCNGeometrySource *vertexSource = vertexSources[0]; // TODO: Parse all the sources
NSInteger stride = vertexSource.dataStride; // in bytes
NSInteger offset = vertexSource.dataOffset; // in bytes
NSInteger componentsPerVector = vertexSource.componentsPerVector;
NSInteger bytesPerVector = componentsPerVector * vertexSource.bytesPerComponent;
NSInteger vectorCount = vertexSource.vectorCount;
SCNVector3 vertices[vectorCount]; // A new array for vertices
// for each vector, read the bytes
for (NSInteger i=0; i<vectorCount; i++) {
// Assuming that bytes per component is 4 (a float)
// If it was 8 then it would be a double (aka CGFloat)
float vectorData[componentsPerVector];
// The range of bytes for this vector
NSRange byteRange = NSMakeRange(i*stride + offset, // Start at current stride + offset
bytesPerVector); // and read the lenght of one vector
// Read into the vector data buffer
[vertexSource.data getBytes:&vectorData range:byteRange];
// At this point you can read the data from the float array
float x = vectorData[0];
float y = vectorData[1];
float z = vectorData[2];
// ... Maybe even save it as an SCNVector3 for later use ...
vertices[i] = SCNVector3Make(x, y, z);
// ... or just log it
NSLog(@"x:%f, y:%f, z:%f", x, y, z);
}
几何元素
这将为您提供所有顶点,但不会告诉您如何使用它们来构建几何。为此,您需要管理顶点索引的geometry元素。
您可以从
geometryElementCount
属性获取某个几何图形的几何图形元素数。然后,您可以使用geometryElementAtIndex:
获得不同的元素。元素可以告诉您使用的顶点是单个三角形还是三角形带。它还会告诉您每个索引的字节数(索引可能是
int
或short
,这对于解码其data
是必需的。关于collada - 从Scenekit提取顶点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17250501/