Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Custom Geometry in SceneKit

I am having trouble trying to get a simple quad with a texture map to run on the iOS Simulator. I have read all other questions on here which deal with similar things and I am stuck. The output looks like this:

enter image description here

The texture is this:

enter image description here

My code is this:

  // v1 +----+ v0
  //    |    |
  // v2 +----+ v3



  SCNVector3 vertices[] = { SCNVector3Make(  5.0,  5.0, 0.0),
                            SCNVector3Make( -5.0,  5.0, 0.0),
                            SCNVector3Make( -5.0, -5.0, 0.0),
                            SCNVector3Make(  5.0, -5.0, 0.0)
  };

  SCNVector3 normals[] = { SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0),
                           SCNVector3Make( 0.0f, 0.0f, 1.0)
  };

  CGPoint textureCoordinates[] = { CGPointMake( 1.0, 1.0),
                                   CGPointMake( 0.0, 1.0),
                                   CGPointMake( 0.0, 0.0),
                                   CGPointMake( 1.0, 0.0)
  };

  NSUInteger vertexCount = 4;


  NSMutableData *indicesData = [NSMutableData data];
  UInt8 indices[] = { 0, 1, 2, 0, 2, 3};
  [indicesData appendBytes:indices length:sizeof(UInt8)*6];
  SCNGeometryElement *indicesElement = [SCNGeometryElement geometryElementWithData:indicesData
                                                                     primitiveType:SCNGeometryPrimitiveTypeTriangles
                                                                    primitiveCount:2
                                                                     bytesPerIndex:sizeof(UInt8)];

  NSMutableData *vertexData = [NSMutableData dataWithBytes:vertices length:vertexCount * sizeof(SCNVector3)];

  SCNGeometrySource *verticesSource = [SCNGeometrySource geometrySourceWithData:vertexData
                                                                       semantic:SCNGeometrySourceSemanticVertex
                                                                    vectorCount:vertexCount
                                                                floatComponents:YES
                                                            componentsPerVector:3
                                                              bytesPerComponent:sizeof(float)
                                                                     dataOffset:0
                                                                     dataStride:sizeof(SCNVector3)];

  NSMutableData *normalData = [NSMutableData dataWithBytes:normals length:vertexCount * sizeof(SCNVector3)];

  SCNGeometrySource *normalsSource = [SCNGeometrySource geometrySourceWithData:normalData
                                                                      semantic:SCNGeometrySourceSemanticNormal
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:3
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(SCNVector3)];

  NSMutableData *textureData = [NSMutableData dataWithBytes:textureCoordinates length:vertexCount * sizeof(CGPoint)];

  SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithData:textureData
                                                                      semantic:SCNGeometrySourceSemanticTexcoord
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:2
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(CGPoint)];
 SCNGeometry *geometry = [SCNGeometry geometryWithSources:@[verticesSource, normalsSource, textureSource]
                                                  elements:@[indicesElement]];


  SCNMaterial *material = [SCNMaterial material];
  //material.diffuse.contents = [UIColor redColor];
  material.diffuse.contents = [UIImage imageNamed:@"diffuse.jpg"];
  material.diffuse.wrapS = SCNWrapModeRepeat;
  material.diffuse.wrapT = SCNWrapModeRepeat;
  material.diffuse.contentsTransform = SCNMatrix4MakeScale( 1.0f, 1.0f, 1.0f);
  material.doubleSided = YES;

  material.normal.wrapS = SCNWrapModeRepeat;
  material.normal.wrapT = SCNWrapModeRepeat;
  //    material.litPerPixel = YES;

  geometry.materials = @[material];

[Edit] I have tried many different things with this code and nothing seems to work. I am yet to see a working example in Objective-C that works on iOS. Any changes to material.diffuse.wrapS has no effect.

I have done this kind of thing in OpenGL before without any issue, but I have been staring at this code for days and can't see my mistake. Any help would be really appreciated.

like image 284
Brett Avatar asked Dec 27 '15 06:12

Brett


1 Answers

@Paul-Jan put me on the right track, which lead me to this answer:

Changing my texture coordinates from CGPoint to float fixes it.

  float textureCoordinates[] = {  1.0, 1.0,
                                  0.0, 1.0,
                                  0.0, 0.0,
                                  1.0, 0.0
  };

  NSMutableData *textureData = [NSMutableData dataWithBytes:textureCoordinates length:vertexCount * sizeof(float) * 2];

  SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithData:textureData
                                                                      semantic:SCNGeometrySourceSemanticTexcoord
                                                                   vectorCount:vertexCount
                                                               floatComponents:YES
                                                           componentsPerVector:2
                                                             bytesPerComponent:sizeof(float)
                                                                    dataOffset:0
                                                                    dataStride:sizeof(float) * 2];

Result:

enter image description here

like image 121
Brett Avatar answered Nov 15 '22 17:11

Brett