Dans SceneKit, j'essaie de créer une simple pièce de géométrie personnalisée avec une texture. J'essaye juste de faire un cube mais ai chaque visage orienté correctement ainsi un SCNBox ne fonctionnera pas.SceneKit Texture de géométrie personnalisée incorrecte
La forme sort parfaitement bien, mais la texture est totalement erronée.
C'est ce que la géométrie vient à la recherche comme:
D'après ce que je comprends, les coordonnées de texture pour chaque visage doit être le même. Mais quand j'ajoute les points pour chaque visage dans le même ordre, il dessine de manière similaire incorrecte. J'ai donc joué avec l'ordre des coordonnées et j'ai obtenu le recto, le dos et une face pour dessiner la plupart du temps correctement. Je n'ai pas été en mesure de trouver un modèle ou une logique à ce qui a causé cela.
L'avant est à l'image de tous les visages.
Voilà comment je le fais:
public struct face {
var topLeft: SCNVector3
var topRight: SCNVector3
var bottomLeft: SCNVector3
var bottomRight: SCNVector3
}
func createCube(startFace: face, endFace: face) -> SCNGeometry {
var vertices: [SCNVector3] = []
var indices: [Int32] = []
var textCords: [vector_float2] = []
// Add table of contents to indices array because we're using polygons
let polygons = 6 // cube so 6 faces
indices.append(4) // front face
indices.append(4) // left face
indices.append(4) // right face
indices.append(4) // top face
indices.append(4) // bottom face
indices.append(4) // back face
// - Convenience Values -
// Indices offsets
let startFaceVertex: Int32 = 0
let endFaceVertex: Int32 = 4
// Vertex indices
let bottomLeftPos: Int32 = 0
let bottomRightPos: Int32 = 1
let topRightPos: Int32 = 2
let topLeftPos: Int32 = 3
// Texture Coordinates
let topLeft = CGPoint(x: 0, y: 1)
let topRight = CGPoint(x: 1, y: 1)
let bottomLeft = CGPoint(x: 0, y: 0)
let bottomRight = CGPoint(x: 1, y: 0)
// Add vertices
vertices.append(startFace.bottomLeft)
vertices.append(startFace.bottomRight)
vertices.append(startFace.topRight)
vertices.append(startFace.topLeft)
vertices.append(endFace.bottomLeft)
vertices.append(endFace.bottomRight)
vertices.append(endFace.topRight)
vertices.append(endFace.topLeft)
// Front Face
indices.append(startFaceVertex + bottomLeftPos)
indices.append(startFaceVertex + bottomRightPos)
indices.append(startFaceVertex + topRightPos)
indices.append(startFaceVertex + topLeftPos)
textCords.append(vector_float2(Float(topLeft.x), Float(topLeft.y)))
textCords.append(vector_float2(Float(topRight.x), Float(topRight.y)))
textCords.append(vector_float2(Float(bottomRight.x), Float(bottomRight.y)))
textCords.append(vector_float2(Float(bottomLeft.x), Float(bottomLeft.y)))
// Left Face
indices.append(startFaceVertex + bottomLeftPos)
indices.append(endFaceVertex + bottomLeftPos)
indices.append(endFaceVertex + topLeftPos)
indices.append(startFaceVertex + topLeftPos)
textCords.append(vector_float2(Float(bottomRight.x), Float(bottomRight.y)))
textCords.append(vector_float2(Float(topLeft.x), Float(topLeft.y)))
textCords.append(vector_float2(Float(bottomLeft.x), Float(bottomLeft.y)))
textCords.append(vector_float2(Float(topRight.x), Float(topRight.y)))
// Top Face
indices.append(endFaceVertex + topLeftPos)
indices.append(endFaceVertex + topRightPos)
indices.append(startFaceVertex + topRightPos)
indices.append(startFaceVertex + topLeftPos)
textCords.append(vector_float2(Float(topLeft.x), Float(topLeft.y)))
textCords.append(vector_float2(Float(topRight.x), Float(topRight.y)))
textCords.append(vector_float2(Float(bottomRight.x), Float(bottomRight.y)))
textCords.append(vector_float2(Float(bottomLeft.x), Float(bottomLeft.y)))
// Right Face
indices.append(endFaceVertex + bottomRightPos)
indices.append(startFaceVertex + bottomRightPos)
indices.append(startFaceVertex + topRightPos)
indices.append(endFaceVertex + topRightPos)
textCords.append(vector_float2(Float(bottomRight.x), Float(bottomRight.y)))
textCords.append(vector_float2(Float(topLeft.x), Float(topLeft.y)))
textCords.append(vector_float2(Float(bottomLeft.x), Float(bottomLeft.y)))
textCords.append(vector_float2(Float(topRight.x), Float(topRight.y)))
// Bottom Face
indices.append(startFaceVertex + bottomLeftPos)
indices.append(startFaceVertex + bottomRightPos)
indices.append(endFaceVertex + bottomRightPos)
indices.append(endFaceVertex + bottomLeftPos)
textCords.append(vector_float2(Float(topLeft.x), Float(topLeft.y)))
textCords.append(vector_float2(Float(topRight.x), Float(topRight.y)))
textCords.append(vector_float2(Float(bottomRight.x), Float(bottomRight.y)))
textCords.append(vector_float2(Float(bottomLeft.x), Float(bottomLeft.y)))
// Back Face
indices.append(endFaceVertex + bottomLeftPos)
indices.append(endFaceVertex + bottomRightPos)
indices.append(endFaceVertex + topRightPos)
indices.append(endFaceVertex + topLeftPos)
textCords.append(vector_float2(Float(topLeft.x), Float(topLeft.y)))
textCords.append(vector_float2(Float(topRight.x), Float(topRight.y)))
textCords.append(vector_float2(Float(bottomRight.x), Float(bottomRight.y)))
textCords.append(vector_float2(Float(bottomLeft.x), Float(bottomLeft.y)))
// Create geometry
let verticesSource = SCNGeometrySource(vertices: vertices)
let uvData = Data(bytes: textCords, count: textCords.count * MemoryLayout<vector_float2>.size)
let textureSource = SCNGeometrySource(data: uvData,
semantic: .texcoord,
vectorCount: textCords.count,
usesFloatComponents: true,
componentsPerVector: 2,
bytesPerComponent: MemoryLayout<Float>.size,
dataOffset: 0,
dataStride: MemoryLayout<vector_float2>.size)
let indexData = Data(bytes: indices,
count: indices.count * MemoryLayout<Int32>.size)
let elements = SCNGeometryElement(data: indexData,
primitiveType: .polygon,
primitiveCount: polygons,
bytesPerIndex: MemoryLayout<Int32>.size)
return SCNGeometry(sources: [verticesSource, textureSource], elements: [elements])
}
Solution
obtenu ce travail, voici mon code pour une version de travail:
public struct face {
var topLeft: SCNVector3
var topRight: SCNVector3
var bottomLeft: SCNVector3
var bottomRight: SCNVector3
}
let topLeft = CGPoint(x: 0, y: 1)
let topRight = CGPoint(x: 1, y: 1)
let bottomLeft = CGPoint(x: 0, y: 0)
let bottomRight = CGPoint(x: 1, y: 0)
func createCube(startFace: face, endFace: face) -> SCNGeometry {
var vertices: [SCNVector3] = []
var indexTable: [Int32] = []
var indices: [Int32] = []
var textCords: [vector_float2] = []
// Front Face
addFace(face: startFace, textureOffset: CGPoint.zero, textureSize: CGSize(width: 1, height: 1), toVertices: &vertices, indexTable: &indexTable, indices: &indices, textCords: &textCords)
// Left Face
let leftFace = face(topLeft: endFace.topLeft, topRight: startFace.topLeft, bottomLeft: endFace.bottomLeft, bottomRight: startFace.bottomLeft, center: SCNVector3Zero, originOffset: startFace.originOffset)
addFace(face: leftFace, textureOffset: CGPoint.zero, textureSize: CGSize(width: 1, height: 1), toVertices: &vertices, indexTable: &indexTable, indices: &indices, textCords: &textCords)
// Top Face
//let topFace = face(topLeft: startFace.topLeft, topRight: endFace.topLeft, bottomLeft: startFace.topRight, bottomRight: endFace.topRight, center: SCNVector3Zero, originOffset: startFace.originOffset)
let topFace = face(topLeft: startFace.topLeft, topRight: endFace.topLeft, bottomLeft: startFace.topRight, bottomRight: endFace.topRight, center: SCNVector3Zero, originOffset: startFace.originOffset)
addFace(face: topFace, textureOffset: CGPoint.zero, textureSize: CGSize(width: 1, height: 1), toVertices: &vertices, indexTable: &indexTable, indices: &indices, textCords: &textCords)
// Right Face
let rightFace = face(topLeft: startFace.topRight, topRight: endFace.topRight, bottomLeft: startFace.bottomRight, bottomRight: endFace.bottomRight, center: SCNVector3Zero, originOffset: startFace.originOffset)
addFace(face: rightFace, textureOffset: CGPoint.zero, textureSize: CGSize(width: 1, height: 1), toVertices: &vertices, indexTable: &indexTable, indices: &indices, textCords: &textCords)
// Bottom Face
let bottomFace = face(topLeft: endFace.bottomLeft, topRight: startFace.bottomLeft, bottomLeft: endFace.bottomRight, bottomRight: startFace.bottomRight, center: SCNVector3Zero, originOffset: startFace.originOffset)
addFace(face: bottomFace, textureOffset: CGPoint.zero, textureSize: CGSize(width: 1, height: 1), toVertices: &vertices, indexTable: &indexTable, indices: &indices, textCords: &textCords)
// Back Face
addFace(face: endFace, textureOffset: CGPoint.zero, textureSize: CGSize(width: 1, height: 1), toVertices: &vertices, indexTable: &indexTable, indices: &indices, textCords: &textCords)
// Create geometry
let verticesSource = SCNGeometrySource(vertices: vertices)
let uvData = Data(bytes: textCords, count: textCords.count * MemoryLayout<vector_float2>.size)
let textureSource = SCNGeometrySource(data: uvData,
semantic: .texcoord,
vectorCount: textCords.count,
usesFloatComponents: true,
componentsPerVector: 2,
bytesPerComponent: MemoryLayout<Float>.size,
dataOffset: 0,
dataStride: MemoryLayout<vector_float2>.size)
var finalIndices: [Int32] = []
finalIndices.append(contentsOf: indexTable)
finalIndices.append(contentsOf: indices)
let indexData = Data(bytes: finalIndices,
count: finalIndices.count * MemoryLayout<Int32>.size)
let elements = SCNGeometryElement(data: indexData,
primitiveType: .polygon,
primitiveCount: indexTable.count,
bytesPerIndex: MemoryLayout<Int32>.size)
return SCNGeometry(sources: [verticesSource, textureSource], elements: [elements])
}
fileprivate func addFace(face: face, textureOffset: CGPoint, textureSize: CGSize, toVertices: inout [SCNVector3], indexTable: inout [Int32], indices: inout [Int32], textCords: inout [vector_float2]) {
toVertices.append(face.topRight)
toVertices.append(face.topLeft)
toVertices.append(face.bottomLeft)
toVertices.append(face.bottomRight)
let polygonPointCount: Int32 = 4
indexTable.append(polygonPointCount)
for _ in 0..<polygonPointCount {
indices.append(Int32(indices.count))
}
textCords.append(vector_float2(Float(bottomRight.x + textureOffset.x + textureSize.width), Float(bottomRight.y + textureOffset.y)))
textCords.append(vector_float2(Float(bottomLeft.x + textureOffset.x + textureSize.width), Float(bottomLeft.y + textureOffset.y)))
textCords.append(vector_float2(Float(topLeft.x + textureOffset.x + textureSize.width), Float(topLeft.y + textureOffset.y)))
textCords.append(vector_float2(Float(topRight.x + textureOffset.x + textureSize.width), Float(topRight.y + textureOffset.y)))
}
Merci beaucoup! J'ai mis à jour mon code et cela a fonctionné parfaitement – harryisaac