我在了解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对象数组(在本例中为顶点数据的源)。

可以用许多不同的方式对这些数据进行编码,并且多个源可以使用具有不同strideoffset的相同数据。源本身具有一堆属性,例如,您可以解码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:获得不同的元素。

元素可以告诉您使用的顶点是单个三角形还是三角形带。它还会告诉您每个索引的字节数(索引可能是intshort,这对于解码其data是必需的。

关于collada - 从Scenekit提取顶点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17250501/

10-14 23:16