mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
When bridging values via the ObjectiveCBridgeable protocol, SILGen has to look up conformances directly, behind the type checker's back. To make sure the ObjectiveCBridgeable conformance is forced, Sema calls useObjectiveCBridgeableConformances() in the right places. However, another conformance we may also need when bridging is the Hashable conformance for a Set or Dictionary's key type. Make sure we force these too, because otherwise when bridging a nil literal nothing needs them in Sema. Fixes <rdar://problem/27470505>.
430 lines
16 KiB
Swift
430 lines
16 KiB
Swift
// RUN: %target-run-simple-swift
|
|
// REQUIRES: executable_test
|
|
|
|
// REQUIRES: objc_interop
|
|
// UNSUPPORTED: OS=watchos
|
|
|
|
import StdlibUnittest
|
|
|
|
|
|
import SceneKit
|
|
|
|
// SceneKit is only available on iOS 8.0 and above and on OS X 10.8 and above.
|
|
|
|
var SceneKitTests = TestSuite("SceneKit")
|
|
|
|
func bytesFromNSData(_ data: NSData) -> [UInt8] {
|
|
let bytePtr = data.bytes.bindMemory(to: UInt8.self, capacity: data.length)
|
|
return Array(UnsafeBufferPointer(start: bytePtr, count: data.length))
|
|
}
|
|
|
|
func floatsFromNSData(_ data: NSData) -> [Float] {
|
|
let floatPtr = data.bytes.bindMemory(to: Float.self, capacity: data.length)
|
|
return Array(UnsafeBufferPointer(start: floatPtr, count: data.length / MemoryLayout<Float>.size))
|
|
}
|
|
|
|
if #available(iOS 8.0, *) {
|
|
SceneKitTests.test("SCNGeometryElement.init(indices:primitiveType:)/Int") {
|
|
let element = SCNGeometryElement(
|
|
indices: [ 1, 2, Int.max, 4, 5, 6 ],
|
|
primitiveType: .triangles)
|
|
|
|
expectEqual(.triangles, element.primitiveType)
|
|
expectEqual(2, element.primitiveCount)
|
|
#if arch(i386) || arch(arm)
|
|
expectEqual(
|
|
[
|
|
1,0,0,0,
|
|
2,0,0,0,
|
|
0xff,0xff,0xff,0x7f,
|
|
4,0,0,0,
|
|
5,0,0,0,
|
|
6,0,0,0,
|
|
],
|
|
bytesFromNSData(element.data as NSData))
|
|
expectEqual(4, element.bytesPerIndex)
|
|
#elseif arch(x86_64) || arch(arm64)
|
|
expectEqual(
|
|
[
|
|
1,0,0,0, 0,0,0,0,
|
|
2,0,0,0, 0,0,0,0,
|
|
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x7f,
|
|
4,0,0,0, 0,0,0,0,
|
|
5,0,0,0, 0,0,0,0,
|
|
6,0,0,0, 0,0,0,0,
|
|
],
|
|
bytesFromNSData(element.data as NSData))
|
|
expectEqual(8, element.bytesPerIndex)
|
|
#else
|
|
_portThisCode()
|
|
#endif
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometryElement.init(indices:primitiveType:)/Int16") {
|
|
let element = SCNGeometryElement(
|
|
indices: [ 1, 2, Int16.max, Int16.max/2, 5, 6 ] as [Int16],
|
|
primitiveType: .triangles)
|
|
|
|
expectEqual(.triangles, element.primitiveType)
|
|
expectEqual(2, element.primitiveCount)
|
|
expectEqual(
|
|
[
|
|
1, 0,
|
|
2, 0,
|
|
0xff, 0x7f,
|
|
0xff, 0x3f,
|
|
5, 0,
|
|
6, 0
|
|
],
|
|
bytesFromNSData(element.data as NSData))
|
|
expectEqual(2, element.bytesPerIndex)
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometryElement.init(indices:primitiveType:)/Triangles") {
|
|
let element = SCNGeometryElement(
|
|
indices: [ 1, 2, UInt8.max, UInt8.max/2, 5, 6 ] as [UInt8],
|
|
primitiveType: .triangles)
|
|
|
|
expectEqual(.triangles, element.primitiveType)
|
|
expectEqual(2, element.primitiveCount)
|
|
expectEqual(
|
|
[ 1, 2, UInt8.max, UInt8.max/2, 5, 6 ],
|
|
bytesFromNSData(element.data as NSData))
|
|
expectEqual(1, element.bytesPerIndex)
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometryElement.init(indices:primitiveType:)/TriangleStrip") {
|
|
let element = SCNGeometryElement(
|
|
indices: [ 1, 2, 3, 4, 5, 6 ] as [UInt8],
|
|
primitiveType: .triangleStrip)
|
|
|
|
expectEqual(.triangleStrip, element.primitiveType)
|
|
expectEqual(4, element.primitiveCount)
|
|
expectEqual(
|
|
[ 1, 2, 3, 4, 5, 6 ],
|
|
bytesFromNSData(element.data as NSData))
|
|
expectEqual(1, element.bytesPerIndex)
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometryElement.init(indices:primitiveType:)/Line") {
|
|
let element = SCNGeometryElement(
|
|
indices: [ 1, 2, 3, 4, 5, 6 ] as [UInt8],
|
|
primitiveType: .line)
|
|
|
|
expectEqual(.line, element.primitiveType)
|
|
expectEqual(3, element.primitiveCount)
|
|
expectEqual(
|
|
[ 1, 2, 3, 4, 5, 6 ],
|
|
bytesFromNSData(element.data as NSData))
|
|
expectEqual(1, element.bytesPerIndex)
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometryElement.init(indices:primitiveType:)/Point") {
|
|
let element = SCNGeometryElement(
|
|
indices: [ 1, 2, 3, 4, 5, 6 ] as [UInt8],
|
|
primitiveType: .point)
|
|
|
|
expectEqual(.point, element.primitiveType)
|
|
expectEqual(6, element.primitiveCount)
|
|
expectEqual(
|
|
[ 1, 2, 3, 4, 5, 6 ],
|
|
bytesFromNSData(element.data as NSData))
|
|
expectEqual(1, element.bytesPerIndex)
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometrySource.init(vertices:)") {
|
|
let source = SCNGeometrySource(vertices: [SCNVector3(1, 2, 3),
|
|
SCNVector3(4, 5, 6)])
|
|
|
|
expectEqual(source.semantic, SCNGeometrySource.Semantic.vertex)
|
|
expectEqual(source.vectorCount, 2)
|
|
expectEqual(source.componentsPerVector, 3)
|
|
|
|
expectEqual(source.bytesPerComponent, MemoryLayout<Float>.size)
|
|
let positions = floatsFromNSData(source.data as NSData)
|
|
expectEqual(positions[2], 3)
|
|
expectEqual(positions[4], 5)
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometrySource.init(normals:)") {
|
|
let source = SCNGeometrySource(normals: [SCNVector3(1, 2, 3),
|
|
SCNVector3(4, 5, 6)])
|
|
|
|
expectEqual(source.semantic, SCNGeometrySource.Semantic.normal)
|
|
expectEqual(source.vectorCount, 2)
|
|
expectEqual(source.componentsPerVector, 3)
|
|
|
|
expectEqual(source.bytesPerComponent, MemoryLayout<Float>.size)
|
|
let normals = floatsFromNSData(source.data as NSData)
|
|
expectEqual(normals[2], 3)
|
|
expectEqual(normals[4], 5)
|
|
}
|
|
|
|
SceneKitTests.test("SCNGeometrySource.init(textureCoordinates:)") {
|
|
let source = SCNGeometrySource(textureCoordinates: [CGPoint(x: 1, y: 2),
|
|
CGPoint(x: 4, y: 5)])
|
|
|
|
expectEqual(source.semantic, SCNGeometrySource.Semantic.texcoord)
|
|
expectEqual(source.vectorCount, 2)
|
|
expectEqual(source.componentsPerVector, 2)
|
|
|
|
let uvs = floatsFromNSData(source.data as NSData)
|
|
expectEqual(uvs[1], 2)
|
|
expectEqual(uvs[3], 5)
|
|
}
|
|
|
|
SceneKitTests.test("SCNSceneSource.entryWithIdentifier(uid:withClass:)")
|
|
.skip(.iOSAny("does not support COLLADA files"))
|
|
.skip(.iOSSimulatorAny("does not support COLLADA files"))
|
|
.skip(.tvOSAny("does not support COLLADA files"))
|
|
.skip(.tvOSSimulatorAny("does not support COLLADA files"))
|
|
.skip(.watchOSAny("does not support COLLADA files"))
|
|
.skip(.watchOSSimulatorAny("does not support COLLADA files"))
|
|
.code {
|
|
let sceneDescription =
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
|
"<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">" +
|
|
" <library_materials>" +
|
|
" <material id=\"material1\">" +
|
|
" <instance_effect url=\"#effect_material1\"/>" +
|
|
" </material>" +
|
|
" <material id=\"material2\">" +
|
|
" <instance_effect url=\"#effect_material2\"/>" +
|
|
" </material>" +
|
|
" </library_materials>" +
|
|
" <library_effects>" +
|
|
" <effect id=\"effect_material1\">" +
|
|
" <profile_COMMON>" +
|
|
" <technique sid=\"common\">" +
|
|
" <blinn>" +
|
|
" <shininess>" +
|
|
" <float>0.022516</float>" +
|
|
" </shininess>" +
|
|
" <transparency>" +
|
|
" <float>1</float>" +
|
|
" </transparency>" +
|
|
" <index_of_refraction>" +
|
|
" <float>1</float>" +
|
|
" </index_of_refraction>" +
|
|
" </blinn>" +
|
|
" </technique>" +
|
|
" </profile_COMMON>" +
|
|
" </effect>" +
|
|
" <effect id=\"effect_material2\">" +
|
|
" <profile_COMMON>" +
|
|
" <technique sid=\"common\">" +
|
|
" <blinn>" +
|
|
" <shininess>" +
|
|
" <float>0.022516</float>" +
|
|
" </shininess>" +
|
|
" <transparency>" +
|
|
" <float>1</float>" +
|
|
" </transparency>" +
|
|
" <index_of_refraction>" +
|
|
" <float>1</float>" +
|
|
" </index_of_refraction>" +
|
|
" </blinn>" +
|
|
" </technique>" +
|
|
" </profile_COMMON>" +
|
|
" </effect>" +
|
|
" </library_effects>" +
|
|
" <library_geometries>" +
|
|
" <geometry id=\"plane\">" +
|
|
" <mesh>" +
|
|
" <source id=\"geometrySource4\">" +
|
|
" <float_array id=\"ID5-array\" count=\"12\">-5 -5 0 5 -5 0 -5 5 0 5 5 0 </float_array>" +
|
|
" <technique_common>" +
|
|
" <accessor source=\"#ID5-array\" count=\"4\" stride=\"3\">" +
|
|
" <param name=\"X\" type=\"float\"/>" +
|
|
" <param name=\"Y\" type=\"float\"/>" +
|
|
" <param name=\"Z\" type=\"float\"/>" +
|
|
" </accessor>" +
|
|
" </technique_common>" +
|
|
" </source>" +
|
|
" <source id=\"geometrySource6\">" +
|
|
" <float_array id=\"ID7-array\" count=\"12\">0 0 1 0 0 1 0 0 1 0 0 1 </float_array>" +
|
|
" <technique_common>" +
|
|
" <accessor source=\"#ID7-array\" count=\"4\" stride=\"3\">" +
|
|
" <param name=\"X\" type=\"float\"/>" +
|
|
" <param name=\"Y\" type=\"float\"/>" +
|
|
" <param name=\"Z\" type=\"float\"/>" +
|
|
" </accessor>" +
|
|
" </technique_common>" +
|
|
" </source>" +
|
|
" <source id=\"geometrySource8\">" +
|
|
" <float_array id=\"ID9-array\" count=\"8\">0 0 1 0 0 1 1 1 </float_array>" +
|
|
" <technique_common>" +
|
|
" <accessor source=\"#ID9-array\" count=\"4\" stride=\"2\">" +
|
|
" <param name=\"S\" type=\"float\"/>" +
|
|
" <param name=\"T\" type=\"float\"/>" +
|
|
" </accessor>" +
|
|
" </technique_common>" +
|
|
" </source>" +
|
|
" <vertices id=\"geometrySource4-vertices\">" +
|
|
" <input semantic=\"POSITION\" source=\"#geometrySource4\"/>" +
|
|
" <input semantic=\"NORMAL\" source=\"#geometrySource6\"/>" +
|
|
" </vertices>" +
|
|
" <triangles count=\"2\" material=\"geometryElement10\">" +
|
|
" <input semantic=\"VERTEX\" offset=\"0\" source=\"#geometrySource4-vertices\"/>" +
|
|
" <input semantic=\"NORMAL\" offset=\"0\" source=\"#geometrySource6\"/>" +
|
|
" <input semantic=\"TEXCOORD\" offset=\"0\" source=\"#geometrySource8\" set=\"1\"/>" +
|
|
" <p>0 1 3 0 3 2 </p>" +
|
|
" </triangles>" +
|
|
" </mesh>" +
|
|
" </geometry>" +
|
|
" <geometry id=\"box\">" +
|
|
" <mesh>" +
|
|
" <source id=\"geometrySource12\">" +
|
|
" <float_array id=\"ID13-array\" count=\"72\">-2.5 -2.5 2.5 -2.5 2.5 2.5 2.5 -2.5 2.5 2.5 2.5 2.5 2.5 -2.5 2.5 2.5 2.5 2.5 2.5 -2.5 -2.5 2.5 2.5 -2.5 2.5 -2.5 -2.5 2.5 2.5 -2.5 -2.5 -2.5 -2.5 -2.5 2.5 -2.5 -2.5 -2.5 -2.5 -2.5 2.5 -2.5 -2.5 -2.5 2.5 -2.5 2.5 2.5 -2.5 2.5 2.5 -2.5 2.5 -2.5 2.5 2.5 2.5 2.5 2.5 -2.5 -2.5 -2.5 -2.5 -2.5 -2.5 2.5 2.5 -2.5 -2.5 2.5 -2.5 2.5 </float_array>" +
|
|
" <technique_common>" +
|
|
" <accessor source=\"#ID13-array\" count=\"24\" stride=\"3\">" +
|
|
" <param name=\"X\" type=\"float\"/>" +
|
|
" <param name=\"Y\" type=\"float\"/>" +
|
|
" <param name=\"Z\" type=\"float\"/>" +
|
|
" </accessor>" +
|
|
" </technique_common>" +
|
|
" </source>" +
|
|
" <source id=\"geometrySource14\">" +
|
|
" <float_array id=\"ID15-array\" count=\"72\">0 0 1 0 0 1 0 0 1 0 0 1 1 0 -4.37114e-08 1 0 -4.37114e-08 1 0 -4.37114e-08 1 0 -4.37114e-08 -8.74228e-08 0 -1 -8.74228e-08 0 -1 -8.74228e-08 0 -1 -8.74228e-08 0 -1 -1 0 1.19249e-08 -1 0 1.19249e-08 -1 0 1.19249e-08 -1 0 1.19249e-08 0 1 -4.37114e-08 0 1 -4.37114e-08 0 1 -4.37114e-08 0 1 -4.37114e-08 0 -1 -4.37114e-08 0 -1 -4.37114e-08 0 -1 -4.37114e-08 0 -1 -4.37114e-08 </float_array>" +
|
|
" <technique_common>" +
|
|
" <accessor source=\"#ID15-array\" count=\"24\" stride=\"3\">" +
|
|
" <param name=\"X\" type=\"float\"/>" +
|
|
" <param name=\"Y\" type=\"float\"/>" +
|
|
" <param name=\"Z\" type=\"float\"/>" +
|
|
" </accessor>" +
|
|
" </technique_common>" +
|
|
" </source>" +
|
|
" <source id=\"geometrySource16\">" +
|
|
" <float_array id=\"ID17-array\" count=\"48\">0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 </float_array>" +
|
|
" <technique_common>" +
|
|
" <accessor source=\"#ID17-array\" count=\"24\" stride=\"2\">" +
|
|
" <param name=\"S\" type=\"float\"/>" +
|
|
" <param name=\"T\" type=\"float\"/>" +
|
|
" </accessor>" +
|
|
" </technique_common>" +
|
|
" </source>" +
|
|
" <vertices id=\"geometrySource12-vertices\">" +
|
|
" <input semantic=\"POSITION\" source=\"#geometrySource12\"/>" +
|
|
" <input semantic=\"NORMAL\" source=\"#geometrySource14\"/>" +
|
|
" </vertices>" +
|
|
" <triangles count=\"12\" material=\"geometryElement18\">" +
|
|
" <input semantic=\"VERTEX\" offset=\"0\" source=\"#geometrySource12-vertices\"/>" +
|
|
" <input semantic=\"NORMAL\" offset=\"0\" source=\"#geometrySource14\"/>" +
|
|
" <input semantic=\"TEXCOORD\" offset=\"0\" source=\"#geometrySource16\" set=\"1\"/>" +
|
|
" <p>0 3 1 0 2 3 4 7 5 4 6 7 8 11 9 8 10 11 12 15 13 12 14 15 16 19 17 16 18 19 20 23 21 20 22 23 </p>" +
|
|
" </triangles>" +
|
|
" </mesh>" +
|
|
" </geometry>" +
|
|
" </library_geometries>" +
|
|
" <library_visual_scenes>" +
|
|
" <visual_scene id=\"scene19\">" +
|
|
" <node id=\"plane_node\" name=\"plane\">" +
|
|
" <instance_geometry url=\"#plane\">" +
|
|
" <bind_material>" +
|
|
" <technique_common>" +
|
|
" <instance_material symbol=\"geometryElement10\" target=\"#material1\"/>" +
|
|
" </technique_common>" +
|
|
" </bind_material>" +
|
|
" </instance_geometry>" +
|
|
" </node>" +
|
|
" <node id=\"box-node\" name=\"box-node\">" +
|
|
" <instance_geometry url=\"#box\">" +
|
|
" <bind_material>" +
|
|
" <technique_common>" +
|
|
" <instance_material symbol=\"geometryElement18\" target=\"#material2\"/>" +
|
|
" </technique_common>" +
|
|
" </bind_material>" +
|
|
" </instance_geometry>" +
|
|
" </node>" +
|
|
" </visual_scene>" +
|
|
" </library_visual_scenes>" +
|
|
" <scene>" +
|
|
" <instance_visual_scene url=\"#scene19\"/>" +
|
|
" </scene>" +
|
|
"</COLLADA>"
|
|
|
|
let sceneData = sceneDescription.data(
|
|
using: .utf8,
|
|
allowLossyConversion: true)!
|
|
let sceneSource = SCNSceneSource(data: sceneData as Data, options: nil)!
|
|
|
|
do {
|
|
var unarchivedPlaneGeometry =
|
|
sceneSource.entryWithIdentifier("plane", withClass: SCNGeometry.self)
|
|
var unarchivedPlaneNode_nil =
|
|
sceneSource.entryWithIdentifier("plane-node", withClass: SCNNode.self)
|
|
|
|
expectNotEmpty(unarchivedPlaneGeometry)
|
|
expectType(Optional<SCNGeometry>.self, &unarchivedPlaneGeometry)
|
|
|
|
expectEmpty(unarchivedPlaneNode_nil)
|
|
}
|
|
|
|
do {
|
|
var unarchivedBoxGeometry =
|
|
sceneSource.entryWithIdentifier("box", withClass: SCNGeometry.self)
|
|
var unarchivedBoxGeometry_nil =
|
|
sceneSource.entryWithIdentifier("box-node", withClass: SCNGeometry.self)
|
|
|
|
expectNotEmpty(unarchivedBoxGeometry)
|
|
expectType(Optional<SCNGeometry>.self, &unarchivedBoxGeometry)
|
|
|
|
expectEmpty(unarchivedBoxGeometry_nil)
|
|
}
|
|
|
|
do {
|
|
var unarchivedBoxNode =
|
|
sceneSource.entryWithIdentifier("box-node", withClass: SCNNode.self)
|
|
var unarchivedBoxNode_nil =
|
|
sceneSource.entryWithIdentifier("box", withClass: SCNNode.self)
|
|
|
|
expectNotEmpty(unarchivedBoxNode)
|
|
expectType(Optional<SCNNode>.self, &unarchivedBoxNode)
|
|
|
|
expectEmpty(unarchivedBoxNode_nil)
|
|
}
|
|
}
|
|
|
|
if #available(OSX 10.10, *) {
|
|
SceneKitTests.test("SCNBoundingVolume.boundingBox/getter") {
|
|
let box = SCNBox(width: 42, height: 0.5, length: 1337, chamferRadius: 0)
|
|
let boundingBox = box.boundingBox
|
|
|
|
expectEqual(boundingBox.max.x, 21)
|
|
expectEqual(boundingBox.max.x, -boundingBox.min.x)
|
|
expectEqual(boundingBox.max.y, 0.25)
|
|
expectEqual(boundingBox.max.y, -boundingBox.min.y)
|
|
expectEqual(boundingBox.max.z, 668.5)
|
|
expectEqual(boundingBox.max.z, -boundingBox.min.z)
|
|
}
|
|
|
|
SceneKitTests.test("SCNBoundingVolume.boundingBox/setter") {
|
|
let max = SCNVector3(42, 0.414, 1337)
|
|
let min = SCNVector3(-42, -0.414, -1337)
|
|
let box = SCNBox(width: 1, height: 2, length: 3, chamferRadius: 0)
|
|
let boxNode = SCNNode(geometry: box)
|
|
|
|
boxNode.boundingBox = (min, max)
|
|
let nodeBoundingBox = boxNode.boundingBox
|
|
|
|
expectEqual(nodeBoundingBox.max.x, max.x)
|
|
expectEqual(nodeBoundingBox.min.x, -max.x)
|
|
expectEqual(nodeBoundingBox.max.y, max.y)
|
|
expectEqual(nodeBoundingBox.min.y, -max.y)
|
|
expectEqual(nodeBoundingBox.max.z, max.z)
|
|
expectEqual(nodeBoundingBox.min.z, -max.z)
|
|
}
|
|
|
|
SceneKitTests.test("SCNBoundingVolume.boundingSphere/getter") {
|
|
let box = SCNBox(width: 2 * 2, height: 3 * 2, length: 6 * 2, chamferRadius: 0)
|
|
let boundingSphere = box.boundingSphere
|
|
|
|
// 2^2 + 3^2 + 6^2 = 7^2
|
|
expectEqual(boundingSphere.radius, 7.0)
|
|
}
|
|
}
|
|
}
|
|
|
|
runAllTests()
|
|
|