ios – 从Orientation获取SCNNode的“up”方面

ios – 从Orientation获取SCNNode的“up”方面,第1张

概述我在SCNScene中有一个SCNBox.一旦场景动画化,SCNBox的变化就是方向,可以通过检查其presentationNode.orientation来看到.此值在SCNVector4中返回.如何根据SCNVector4中返回的值确定SCNBox的哪一侧是朝上的一侧? 我试图规范化数据并提出以下数据 Side 1 = (-x, 0, 0, +x)Side 2 = (0, -x, 0 +y) 我在SCNScene中有一个SCNBox.一旦场景动画化,SCNBox的变化就是方向,可以通过检查其presentationNode.orIEntation来看到.此值在SCNVector4中返回.如何根据SCNVector4中返回的值确定SCNBox的哪一侧是朝上的一侧?

我试图规范化数据并提出以下数据

SIDe 1 = (-x,+x)SIDe 2 = (0,-x,0 +y)SIDe 3 = (-x,+x,-y,y)SIDe 4 = (x,x,y,y)SIDe 5 = (-x,+y,0)SIDe 6 = (-x,-x)

不幸的是,这并不总是正确的,并且检查它有时偶尔会返回无效的边.

是否有可靠的方法从几何的方向属性确定SCNBox的朝上一侧?

编辑:@H_404_20@根据Toyos的回答,我提出了以下代码,但这些代码无效.希望这有助于更接近最终目标.我还使用了在Extracting vertices from scenekit找到的代码来获取我的SCNBoxNode的顶点.

- (NSNumber *)valueForRotation:(SCNVector4)rotation andGeometry:(SCNGeometry*)geometry {    SCNVector4 inverse = SCNVector4Make(rotation.x,rotation.y,rotation.z,-rotation.w);    CAtransform3D transform = CAtransform3DMakeRotation(inverse.w,inverse.x,inverse.y,inverse.z);    GLKMatrix4 matrix = GLKMatrix4Make(transform.m11,transform.m12,transform.m13,transform.m14,transform.m21,transform.m22,transform.m23,transform.m24,transform.m31,transform.m32,transform.m33,transform.m34,transform.m41,transform.m42,transform.m43,transform.m44);    GLKVector4 vector = GLKVector4Make(rotation.x,rotation.w);    GLKVector4 finalVector = GLKMatrix4MultiplyVector4(matrix,vector);    NSArray *vertexSources = [geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticVertex];    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    NSLog(@"vetor count %i",vectorCount);    float highestProduct = 0;    int highestVector = -1;    NSMutableArray *highVectors;    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,z);        // ... or just log it         NSLog(@"x:%f,y:%f,z:%f",z);        float product = (x * finalVector.x) + (y * finalVector.y) +  (z * finalVector.z);        if (product > highestProduct) {            highestProduct = product;            highestVector = i;        }    }    NSLog(@"highestProduct = %f",highestProduct);    NSLog(@"highestVector = %i",highestVector);    NSLog(@"top verticy = %f,%f,%f",vertices[highestVector].x,vertices[highestVector].y,vertices[highestVector].z);    return [NSNumber numberWithInt:highestVector];}
解决方法 这是一个返回面朝上的面的索引的方法.它假定“BoxNode”是由6个面组成的框,具有以下(任意)顺序:前/右/后/左/上/下.它返回面朝上的面部索引. @H_404_20@别忘了导入. @H_404_20@对于任意网格,你必须使用面法线而不是“Boxnormals”(这是不明显的计算,因为SceneKit网格每个顶点有一个法线,而不是每个面一个法线,所以你必须计算每个面的法线你自己).

- (NSUInteger) BoxUpIndex:(SCNNode *)BoxNode{    SCNVector4 rotation = BoxNode.rotation;    SCNVector4 invRotation = rotation; invRotation.w = -invRotation.w;    SCNVector3 up = SCNVector3Make(0,1,0);    //rotate up by invRotation    SCNMatrix4 transform = SCNMatrix4MakeRotation(invRotation.w,invRotation.x,invRotation.y,invRotation.z);    GLKMatrix4 glktransform = SCNMatrix4ToGLKMatrix4(transform);    GLKVector3 glkUp = SCNVector3ToGLKVector3(up);    GLKVector3 rotatedUp = GLKMatrix4MultiplyVector3(glktransform,glkUp);    //build Box normals (arbitrary order here)    GLKVector3 Boxnormals[6] = {{{0,1}},{{1,0}},{{0,-1}},{{-1,-1,};    int bestIndex = 0;    float maxDot = -1;    for(int i=0; i<6; i++){        float dot = GLKVector3DotProduct(Boxnormals[i],rotatedUp);        if(dot > maxDot){            maxDot = dot;            bestIndex = i;        }    }    return bestIndex;}
总结

以上是内存溢出为你收集整理的ios – 从Orientation获取SCNNode的“up”方面全部内容,希望文章能够帮你解决ios – 从Orientation获取SCNNode的“up”方面所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1077041.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存