2015-10-08 2 views
1

Я пытаюсь переписать этот код для iPhone:C3DRendererContextSetupResidentMeshSourceAtLocation - двойной не поддерживается в SceneKit

https://github.com/d-ronnqvist/DRMeshGeometry

код работает в тренажере, но iPhone возвращает эти ошибки:

2015-10-08 12:04:37.564 3dtest[4253:1581829] SceneKit: error, C3DRendererContextSetupResidentMeshSourceAtLocation - double not supported 
2015-10-08 12:04:37.566 3dtest[4253:1581829] SceneKit: error, C3DSourceAccessorToVertexFormat - invalid vertex format 
/BuildRoot/Library/Caches/com.apple.xbs/Sources/Metal/Metal-54.31/Framework/MTLVertexDescriptor.mm:761: failed assertion `Unused buffer at index 18.' 

Ошибка в этой функции:

- (SCNGeometry *)geometryWithFunction:(DRMeshFunction)function 
    { 
    self.function = function; 

    NSUInteger width = self.stepsPerAxisCounts.one; 
    NSUInteger depth = self.stepsPerAxisCounts.two; 

    NSUInteger pointCount = width * depth; 

    SCNVector3 vertices[pointCount]; 
    SCNVector3 normals[pointCount]; 
    CGPoint  textures[pointCount]; 


    NSUInteger numberOfIndices = (2*width)*(depth); 
    if (depth%4==0) numberOfIndices += 2; 

    short indices[numberOfIndices]; 


    short lastIndex = 0; 
    for (int row = 0 ; row<width-1 ; row++) { 
     BOOL isEven = row%2 == 0; 
     for (int col = 0 ; col<depth ; col++) { 

      if (isEven) { 
       indices[lastIndex] = row*width + col; 
       lastIndex++; 
       indices[lastIndex] = (row+1)*width + col; 
       if (col == depth-1) { 
        lastIndex++; 
        indices[lastIndex] = (row+1)*width + col; 
       } 
      } else { 
       indices[lastIndex] = row*width + (depth-1-col); 
       lastIndex++; 
       indices[lastIndex] = (row+1)*width + (depth-1-col); 
       if (col == depth-1) { 
        lastIndex++; 
        indices[lastIndex] = (row+1)*width + (depth-1-col); 
       } 
      } 
      lastIndex++; 
     } 
    } 

    // Generate the mesh by calculating the vector, normal 
    // and texture coordinate for each x,z pair. 
    for (int row = 0 ; row<width ; row++) { 
     for (int col = 0 ; col<depth ; col++) { 

      CGFloat one = (float)col/(width-1) * (self.rangeOne.max - self.rangeOne.min) + self.rangeOne.min; 
      CGFloat two = (float)row/(depth-1) * (self.rangeTwo.max - self.rangeTwo.min) + self.rangeTwo.min; 

      SCNVector3 value = [self vectorForFunction:function one:one two:two]; 

      vertices[col + row*depth] = value; 

      CGFloat delta = 0.001; 
      SCNVector3 dx = vectorSubtract(value, 
              [self vectorForFunction:function one:one+delta two:two]); 

      SCNVector3 dz = vectorSubtract(value, 
              [self vectorForFunction:function one:one two:two+delta]); 

      normals[col + row*depth] = normalize(crossProduct(dz, dx)); 


      textures[col + row*depth] = CGPointMake(col/(float)width*self.textureRepeatCounts.one, 
                row/(float)depth*self.textureRepeatCounts.two); 
     } 
    } 

    // Create geometry sources for the generated data 

    SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithVertices:vertices   count:pointCount]; 
    SCNGeometrySource *normalSource = [SCNGeometrySource geometrySourceWithNormals:normals    count:pointCount]; 
    SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithTextureCoordinates:textures count:pointCount]; 


    // Configure the indices that was to be interpreted as a 
    // triangle strip using 

    SCNGeometryElement *element = 
    [SCNGeometryElement geometryElementWithData:[NSData dataWithBytes:indices 
                   length:sizeof(short[numberOfIndices])] 
            primitiveType:SCNGeometryPrimitiveTypeTriangleStrip 
           primitiveCount:numberOfIndices 
            bytesPerIndex:sizeof(short)]; 

    // Create geometry from these sources 
    SCNGeometry *geometry = [SCNGeometry geometryWithSources:@[vertexSource, normalSource, textureSource] 
               elements:@[element]]; 

    // Since the builder exposes a geometry with repeating texture 
    // coordinates it is configured with a repeating material 

    SCNMaterial *repeatingTextureMaterial = [SCNMaterial material]; 
    repeatingTextureMaterial.doubleSided = YES; 

    // Possibly repeat all the materials texture coordintes here 
    repeatingTextureMaterial.specular.contents = [UIColor colorWithWhite:0.3 alpha:1.0]; 
    repeatingTextureMaterial.shininess = .1250; 

    geometry.materials = @[repeatingTextureMaterial]; 

    return geometry; 
} 

I really do not know what to try 

ответ

1

У меня подобная проблема, и я нашел обходное решение.

Ошибка указывает на то, что double не поддерживается, и на самом деле это координата текстуры, которая использует двойные значения из-за CGPoint.

Итак, решение прост, создайте еще одну структуру для замены CGPoint, как и коды ниже.

Изменить

CGPoint textures[pointCount]; 
textures[col + row*depth] = CGPointMake(col/(float)width*self.textureRepeatCounts.one, row/(float)depth*self.textureRepeatCounts.two); 

в

typedef struct FloatPoint { 
    float x; 
    float y; 
} FloatPoint; 

FloatPoint textures[pointCount]; 

textures[col + row*depth] = (FloatPoint){col/(float)width*self.textureRepeatCounts.one, row/(float)depth*self.textureRepeatCounts.two}; 

Изменить

SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithTextureCoordinates:textures count:pointCount]; 

в

SCNGeometrySource *textureSource = [SCNGeometrySource geometrySourceWithData:[NSData dataWithBytes:textures length:sizeof(textures)] 
                    semantic:SCNGeometrySourceSemanticTexcoord 
                   vectorCount:pointCount 
                  floatComponents:YES 
                 componentsPerVector:2 
                  bytesPerComponent:sizeof(float) 
                    dataOffset:offsetof(FloatPoint, x) 
                    dataStride:sizeof(FloatPoint)]; 
0

В Swift, это:

let textureData = NSData(bytes: textCoords, length: textCoords.count * sizeof(FloatPoint.self)) 
let textSource = SCNGeometrySource(
    data: textureData as Data, 
    semantic: SCNGeometrySourceSemanticTexcoord, 
    vectorCount: textCoords.count, 
    floatComponents: true, 
    componentsPerVector: 2, 
    bytesPerComponent: sizeof(Float.self), 
    dataOffset: 0, 
    dataStride: sizeof(FloatPoint.self) 
) 

(просто установить смещение 0)

Смежные вопросы