从场景包中提取顶点 [英] Extracting vertices from scenekit

查看:41
本文介绍了从场景包中提取顶点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解 Scenekit 几何图形时遇到问题.

I'm having a problem with understanding scenekit geometery.

我有来自 Blender 的默认立方体,我导出为 collada (DAE),并且可以将它带入 Scenekit ......一切都很好.

I have the default cube from Blender, and I export as collada (DAE), and can bring it into scenekit.... all good.

现在我想查看立方体的顶点.在 DAE 中,我可以看到Cube-mesh-positions-array"的以下内容,

Now I want to see the vertices for the cube. In the DAE I can see the following for the "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 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 中做的是取回顶点,使用如下所示:

Now what I'd like to do in scenekit, is get the vertices back, using something like the following:

SCNGeometrySource *vertexBuffer = [[cubeNode.geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticVertex] objectAtIndex:0];

如果我处理 vertexBuffer(我已经尝试了多种查看数据的方法),它似乎不正确.

If I process the vertexBuffer (I've tried numerous methods of looking at the data), it doesn't seem correct.

有人可以解释一下SCNGeometrySourceSemanticVertex"给我的是什么,以及如何正确提取顶点数据?我想看到的是:

Can somebody explain what "SCNGeometrySourceSemanticVertex" is giving me, and how to extract the vertex data properly? What I'd like to see is:

X = "float"
Y = "float"
Z = "float"

我也在研究以下类/方法,它们看起来很有希望(这里有一些很好的数据值),但是来自 gmpe 的数据似乎是空的,有人能够解释SCNGeometryElement"的数据属性包含什么?

Also I was investigating the following class / methods, which looked promising (some good data values here), but the data from gmpe appears empty, is anybody able to explain what the data property of "SCNGeometryElement" contains?

SCNGeometryElement *gmpe = [theCurrentNode.geometry geometryElementAtIndex:0];

谢谢,非常感谢您的帮助,

Thanks, assistance much appreciated,

D

推荐答案

几何源

当你调用 geometrySourcesForSemantic: 时,你会得到一个 SCNGeometrySource 对象数组,在你的例子中是顶点数据的来源.

The geometry source

When you call geometrySourcesForSemantic: you are given back an array of SCNGeometrySource objects with the given semantic in your case the sources for the vertex data).

这些数据可以用多种不同的方式编码,多个来源可以使用具有不同strideoffset的相同数据.源本身有一堆属性让你能够解码 data 像例如

This data could have been encoded in many different ways and a multiple sources can use the same data with a different stride and offset. The source itself has a bunch of properties for you to be able to decode the data like for example

  • dataStride
  • dataOffset
  • vectorCount
  • componentsPerVector
  • bytesPerComponent

您可以使用这些组合来确定要读取 data 的哪些部分并从中创建顶点.

You can use combinations of these to figure out which parts of the data to read and make vertices out of them.

步幅告诉您应该步进多少字节才能到达下一个向量,而偏移量则告诉您在到达该向量的数据的相关部分之前应该从该向量的开头偏移多少字节.您应该为每个向量读取的字节数是 componentsPerVector * bytesPerComponent

The stride tells you how many bytes you should step to get to the next vector and the offset tells you how many bytes offset from the start of that vector you should offset before getting to the relevant pars of the data for that vector. The number of bytes you should read for each vector is componentsPerVector * bytesPerComponent

读出单个几何源的所有顶点的代码看起来像这样

Code to read out all the vertices for a single geometry source would look something like this

// 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);
}

几何元素

这将为您提供所有顶点,但不会告诉您如何使用它们来构造几何体.为此,您需要管理顶点索引的几何元素.

The geometry element

This will give you all the vertices but won't tell you how they are used to construct the geometry. For that you need the geometry element that manages the indices for the vertices.

您可以从 geometryElementCount 属性获取一个几何图形的几何元素数量.然后你可以使用 geometryElementAtIndex: 获取不同的元素.

You can get the number of geometry elements for a piece of geometry from the geometryElementCount property. Then you can get the different elements using geometryElementAtIndex:.

该元素可以告诉您顶点是使用单个三角形还是三角形条.它还告诉您每个索引的字节数(索引可能是 ints 或 shorts,这是解码其 data 所必需的.

The element can tell you if the vertices are used a individual triangles or a triangle strip. It also tells you the bytes per index (the indices may have been ints or shorts which will be necessary to decode its data.

这篇关于从场景包中提取顶点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆