我试图规范化数据并提出以下数据
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”方面所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)