我正在尝试为iPhone重写此代码:
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
答案 0 :(得分:1)
我遇到了类似的问题,我找到了解决方法。
错误表示不支持double,实际上它是因CGPoint而使用double值的纹理坐标。
所以解决方案很简单,创建另一个结构来替换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)];