Ios 组合两个或多个计量单位

Ios 组合两个或多个计量单位,ios,objective-c,xcode,scenekit,Ios,Objective C,Xcode,Scenekit,我用这种方法抓取一幅UIImage并将其转换为3D模型。但是,这意味着我添加了大量节点。。我在想,也许可以通过将所有几何体添加到单个节点中来优化它。有没有办法做到这一点 这是密码 static inline SCNNode* S2NNode(const UIImage* sprite) { SCNNode *spriteNode = [SCNNode node]; CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataPro

我用这种方法抓取一幅UIImage并将其转换为3D模型。但是,这意味着我添加了大量节点。。我在想,也许可以通过将所有几何体添加到单个节点中来优化它。有没有办法做到这一点

这是密码

static inline SCNNode* S2NNode(const UIImage* sprite) {
  SCNNode *spriteNode = [SCNNode node];
  CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(sprite.CGImage));
  const UInt8* data = CFDataGetBytePtr(pixelData);
  for (int x = 0; x < sprite.size.width; x++)
  {
    for (int y = 0; y < sprite.size.height; y++)
    {
      int pixelInfo = ((sprite.size.width * y) + x) * 4;
      UInt8 alpha = data[pixelInfo + 3];
      if (alpha > 3)
      {
        UInt8 red   = data[pixelInfo];
        UInt8 green = data[pixelInfo + 1];
        UInt8 blue  = data[pixelInfo + 2];
        UIColor *color = [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
        SCNNode *pixel = [SCNNode node];
        pixel.geometry = [SCNBox boxWithWidth:1.001 height:1.001 length:1.001 chamferRadius:0];
        pixel.geometry.firstMaterial.diffuse.contents = color;
        pixel.position = SCNVector3Make(x - sprite.size.width / 2.0,
                                        y - sprite.size.height / 2.0,
                                        0);
        [spriteNode addChildNode:pixel];
      }
    }
  }
  CFRelease(pixelData);
  //The image is upside down and I have no idea why.
  spriteNode.rotation = SCNVector4Make(1, 0, 0, M_PI);
  return spriteNode;
}
静态内联SCNNode*S2NNode(const UIImage*sprite){
SCNNode*spriteNode=[SCNNode节点];
CFDataRef pixelData=CGDataProviderCopyData(CGImageGetDataProvider(sprite.CGImage));
const UInt8*data=CFDataGetBytePtr(像素数据);
对于(int x=0;x3)
{
UInt8红色=数据[pixelInfo];
UInt8绿色=数据[pixelInfo+1];
UInt8蓝色=数据[pixelInfo+2];
UIColor*color=[UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
SCNNode*像素=[SCNNode节点];
pixel.geometry=[SCNBox Box With Width:1.001 height:1.001 length:1.001 chamferRadius:0];
pixel.geometry.firstMaterial.diffuse.contents=颜色;
pixel.position=scinvector3make(x-sprite.size.width/2.0,
y-精灵尺寸高度/2.0,
0);
[spriteNode addChildNode:pixel];
}
}
}
CFRelease(pixelData);
//图像颠倒了,我不知道为什么。
spriteNode.rotation=scinvector4make(1,0,0,M_-PI);
返回spriteNode;
}

此答案解决了最初提出的问题-如何合并几何体。然而,合并几何体似乎并不是解决实际问题的办法——如何获得具有一定厚度、性能良好的像素化“精灵”。看看吧


SCNNode
方法将节点子节点的所有几何图形组合到一个具有单个几何图形的节点中。这将减少场景处理开销,并在单个OpenGL绘图调用中渲染。。。但它也会使立方体不能独立移动,并且所有立方体都使用相同的材料,因此它们不会有不同的颜色。此外,根据您希望立方体的排列方式,您可能会将更多的顶点数据推送到GPU,这仍然会影响您的性能


根据你想要达到什么样的效果,可能有更好的解决方案

发布一个单独的答案,因为你的评论表明你实际上在寻找的并不是你想要的——我留下另一个答案,因为它回答了最初提出的问题,即使它不能解决你的问题


因此,听起来你真正需要的并不是一组立方体,每个立方体都可以独立移动,每个立方体都有自己的颜色,而是将2D形状挤压成3D形状——具体来说,是由图像的不透明像素形成的形状:

在这种情况下,制作一堆多维数据集确实会影响性能,也会影响渲染结果。查看此详细信息(来自使用大量多维数据集方法的版本):

这些小白点来自两个立方体相交处的舍入误差。这里的问题是,无论您是否使用
flattedClone
,推送到GPU的几何体数据描述了大量的多边形,这些多边形要么不可见(因为它们位于两个立方体之间),要么不相关(因为两个相邻立方体的共享面也可以是一个多边形)。以下是我对大量立方体方法测试的性能指标:

这是408个绘图,4.9K多边形,14.7K顶点。在iPadAir上旋转该模型每秒可获得14帧,真恶心

您可以使用类从Bézier路径生成拉伸形状。其中的诀窍是从不透明像素的形状生成最简单的路径。(您需要的是形成形状轮廓的路径,而不是每个像素的一组方形路径的并集,否则您将直接回到立方体问题。)

这是计算几何的一个重要部分,但是。还有一些外部工具可以为您离线进行跟踪(大多数工具都是为了在SpriteKit成为iOS 8/OS X 10.10中的SpriteKit功能之前为SpriteKit制作基于sprite的物理实体而设计的):

获得路径后,可以从中制作
SCNShape
,将图像纹理映射到形状的前面(如果愿意,也可以映射到后面),并对侧面使用平面颜色:

UIImage *image = [UIImage imageNamed:@"sprite"];
UIBezierPath *path = PathFromImage(image); // Make or load your path here
SCNNode *node = [SCNNode nodeWithGeometry:[SCNShape shapeWithPath:path extrusionDepth:1]];
SCNMaterial *face = [SCNMaterial material];
face.diffuse.contents = image;
face.diffuse.magnificationFilter = SCNFilterModeNone;
SCNMaterial *side = [SCNMaterial material];
side.diffuse.contents = [UIColor blackColor];
side.specular.contents = [UIColor whiteColor];
node.geometry.materials = @[ face, side, side ];
这是使用
SCNShape
的仪表:


我们将数字减少了两个数量级,相应地,帧速率要高得多-当模型旋转时,我无法将其降至60 fps以下。

此代码应该用于小型spritesTry,不使用CGSizeMake(100100)上的图像。您想做什么?为图像的每个像素制作立方体确实不利于性能。根据您想要实现的目标,可能还有其他解决方案。我希望为我放置的所有立方体创建一个几何体。所以我想知道是否有一种方法可以将所有这些几何图形添加到一起,这样可能会有助于提高性能。颜色保持不变。然而,它仍然是一样密集的GPU。如何从SCNNode创建顶点数据?取决于您试图对其执行的操作。问另一个问题或编辑你的原始问题,并描述你的最终目标-达到目标的步骤可能不是你想象的等待。你在这里得到的结果只是另一个框。但是SceneKit不够聪明,无法检测到这一点,并且顶点的数量保持不变。您不能使用一个单独的框来使用
SCNFilter映射纹理吗