ãé·ãéäžæçãªç¶æ ã§æ€çããŠããã¢ããªã±ãŒã·ã§ã³ããçªç¶ãŠãŒã¶ãŒã®éã§äººæ°ãç²åŸããå©çãäžããããã«ãªããŸãã èšããŸã§ããªãããã®ãããªç¶æ³ã§ã¯ããããéçºããã³æŽæ°ããããšããå§ãããŸãã 1ã€æªãã®ã¯ã補åã®ãœãŒã¹ã³ãŒããéèŠã®ãªãææã«é埳çã«é³è åããŠããããã®æŽæ°ã«è²»ããããæéã¯ãæ°ãããœãŒã¹ããŒãããéçºãããªãœãŒã¹ã«å¹æµããããšãå€æããå Žåãããããšã§ãã Human Anatomy 3Dãããžã§ã¯ãã§äœæ¥ããŠãããšãã«ãåæ§ã®åé¡ã«çŽé¢ããŸããã ãã®èšäºã§ã¯ãUnity3DãœãŒã¹ãããã€ãã£ãããŒãžã§ã³ãžã®ã¢ããªã±ãŒã·ã§ã³ã®æ°ããããŒãžã§ã³ã®ç§»è¡ãã©ã®ããã«è¡ããããã説æããããã»ã¹ã§çºçããåé¡ã®ããã€ãã匷調ããŸãã

ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ãæ°å¹Žåã«ã¯ãã¹ãã©ãããã©ãŒã ã®Unity3Dã§äœæãããŸããã ãã°ããããŠãã¯ãã¹ãã©ãããã©ãŒã ã¯ç¡é¢ä¿ã«ãªããApp Storeã®ããŒãžã§ã³ã¯ãŠãŒã¶ãŒã®ããã€ã¹äžã§å€ãã®ã¹ããŒã¹ãå æãç¶ããŸããã ãŸããUnity3Dãšã³ãžã³ã®æ©èœã¯ãæ©èœã®å®è£ ã«å¯ŸããŠåé·ã§ããã3Dãªããžã§ã¯ãã衚瀺ããããã«å¿ èŠãªã®ã¯ãããããšã®åºæ¬çãªçžäºäœçšããã³ã¢ãã¡ãŒã·ã§ã³ã®è¡šç€ºã ãã§ããã äžèšãèæ ®ããŠããã€ãã£ãiOSããã³macOSãœãŒã¹ã§ããŒãžã§ã³ãæŽæ°ããSceneKitã䜿çšããŠ3Dãªããžã§ã¯ããæäœããããã®ã¢ãžã¥ãŒã«ãå®è£ ããããšã«ããŸããã ãã®æ±ºå®ã¯ãäž»ã«ãã®ããŒã«ã«ç²ŸéããŠãããšããäºå®ã«ãã£ãŠæ±ºå®ãããŸããã
SceneKitã·ã§ãŒãã¬ãã¥ãŒ
SceneKitã¯ã3次å ãªããžã§ã¯ããæäœããããã«èšèšãããé«ã¬ãã«ã®ãã¬ãŒã ã¯ãŒã¯ã§ãã ç©çãšã³ãžã³ãããŒãã£ã¯ã«ãžã§ãã¬ãŒã¿ãããã³äŸ¿å©ãªAPIãå«ãŸããŠããŸãã SceneKitã¯ã·ãŒã³ã°ã©ãã«åºã¥ããŠããŸãã ãã®ã¢ãããŒãã¯ã3Dãšãã£ã¿ãŒïŒBlenderãLightwaveãªã©ïŒãšåæ§ã«ãã²ãŒã ãšã³ãžã³ïŒUnityãCocosãªã©ïŒã§åºã䜿çšãããŠããŸãã ã·ãŒã³ã°ã©ãã®è©³çŽ°ã«ã€ããŠã¯ã ãã¡ããã芧ãã ãã ã å žåçãªæ§é ãèããŠã¿ãŸãããã

ãã®æ§é ã®äž»ãªèŠçŽ ã¯ããŒãïŒSCNNodeïŒã§ãäœçœ®ãå転è§åºŠãã¹ã±ãŒã«ã«é¢ããæ å ±ãå«ãŸããŠããŸãã åããŒãã®äœçœ®ãå転ãããã³ã¹ã±ãŒã«ã¯ã芪ããŒããåºæºã«ããŠæ±ºå®ãããŸãã
- SCNGeometryã¯ããªããžã§ã¯ãã®åœ¢ç¶ãšäžé£ã®ãããªã¢ã«ãä»ãã衚瀺ãå®çŸ©ããŸãã
- SCNCameraã¯ãã·ãŒã³ãèŠããã€ã³ããæ åœããŸãïŒæ ç»ãæ®åœ±ãããšãã®ã«ã¡ã©ã«äŒŒãŠããŸãïŒã
- SCNLightã¯ç §æãæ åœããŸãã ãã®äœçœ®ã¯ãã·ãŒã³å ã®ãã¹ãŠã®ãªããžã§ã¯ãã«åœ±é¿ããŸãã
æ§é ãããããããã«ãã«ãŒããªããžã§ã¯ãã¯SCNSceneã§ãããã«ãŒãããŒããžã®ãªã³ã¯ãå«ãŸããŠããŸãã ã·ãŒã³ã®æ§é å šäœãæ§ç¯ãããã®ã¯ããã®ããŒãã«é¢ããŠã§ãã
次ã«ããããžã§ã¯ãã§ã©ã®ããã«äœ¿çšãããããèŠãŠã¿ãŸãããã æåã«ãã·ãŒã³ãªããžã§ã¯ãïŒSCNSceneïŒãäœæãããå®æããã·ãŒã³ãšã¢ãã«ãããŒããããŸããã ã·ãŒã³ãšãã¯ã¹ãã£ãä¿åããããã«ãæšå¥šããã.scnassetsãã©ã«ããŒã䜿çšãããŸããã ãã®å ŽåãXcodeã¯ããããæé©åããããã€ã¹ã§æ倧ã®ããã©ãŒãã³ã¹ãå®çŸããããã§ãã COLLADA圢åŒïŒ* .daeïŒã§ãšãã£ã¿ãŒããã·ãŒã³ãã€ã³ããŒãããŸããã .scnassetsããã·ãŒã³ãããŒãããäŸã次ã«ç€ºããŸãã
Objective-CïŒ
SCNScene *scene = [SCNScene sceneNamed:@" "];
ã¹ã€ããïŒ
let scene = SCNScene(named: " ")
ãã®çµæãããŒããããã·ãŒã³ã®ãªããžã§ã¯ãã®éå±€å šäœãã·ãŒã³ã®ã«ãŒãããŒãïŒrootNodeïŒã«è¿œå ãããŸãã ãã®åŸãã¹ããŒãžäžã§ã¢ãã«ãèŠã€ããŠããã¯ã¹ãã£ãå«ããããªã¢ã«ãè¿œå ãããšãããšå€æããŸãããããã¯ãã€ã¡ãŒãžã§ãããåã.scnassetsã«ä¿åãããŠããŸãã
Objective-C iOSïŒ
SCNNode *meshNode = [scene.rootNode childNodeWithName:@" " recursively:true]; meshNode.geometry.materials.firstObject.diffuse.contents = [UIImage imageNamed:@" "];
Swift macOSïŒ
let meshNode: SCNNode? = mydae.rootNode.childNode(withName: " ", recursively: true) meshNode?.geometry?.materials.first?.diffuse.contents = NSImage(named: " ")
ã芧ã®ãšãããç®çã®ããŒãã®æ€çŽ¢ã¯ååã ãã§å®è¡ãããŸãã ååž°çãã©ã¡ãŒã¿ãŒã¯ãã·ãŒã³ã°ã©ããããã«æ·±ãæ€çŽ¢ããããçŸåšã®ããŒãã®åããŒãã«éå®ããã®ã«ååãã©ããã決å®ããŸãã å¿ èŠãªããŒããèŠã€ãããããã®äžã«ããæåã®ãããªã¢ã«ãéžæããéžæãããã¯ã¹ãã£ãå²ãåœãŠãŸãã
次ã«ãã«ã¡ã©ãå ¥åããå¿ èŠããããŸãã ãããè¡ãã«ã¯ã2ã€ã®ããŒããäœæããŠã·ãŒã³éå±€ã«è¿œå ããŸããcameraNodeã¯ã«ã¡ã©ã«ãªããcameraRootã¯ã«ã¡ã©ãã¢ã¿ãããããã«ã¡ã©ã移åããçžå¯Ÿäœçœ®ã«ãªããŸãã
Objective-C iOSïŒ
SCNNode *cameraNode = [SCNNode node]; cameraNode.camera = [SCNCamera camera]; SCNNode * cameraRoot = [SCNNode node]; cameraNode.position = SCNVector3Make(0, 0, 3); [cameraRoot addChildNode:cameraNode]; [scene.rootNode addChildNode:cameraRoot];
Swift macOSïŒ
let cameraNode = SCNNode() cameraNode.camera = SCNCamera() let cameraRoot = SCNNode() cameraNode.position = SCNVector3Make(0, 0, 3) cameraRoot.addChildNode(cameraNode) scene.rootNode.addChildNode(cameraRoot)
ããã¯ãã«ã¡ã©ã§ã®äœæ¥ã®å©äŸ¿æ§ã®ããã«è¡ãããŸãããã®å Žåããã¹ãŠã®ç§»åã¯åºå®ç¹ãåºæºã«ããŠå®è¡ãããããã§ããããã¯ãããšãã°ã«ã¡ã©ããªããžã§ã¯ãã®åšããé£è¡ããå¿ èŠãããå Žåã«ãã䟿å©ã§ãã
ã·ãŒã³ã衚瀺ããã«ã¯ãSceneKit Viewã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ã䜿çšããŸããããã¯ãã¢ããªã±ãŒã·ã§ã³ç»é¢ã«è¿œå ãããŸãã

ãããžã§ã¯ãå ã«ç¹å®ã®ç §æã¯å¿ èŠãªãã®ã§ãã¹ããŒãžã«å æºãè¿œå ããŸããã 代ããã«ãããã©ã«ãã®ç §æã䜿çšããŠãã ããã SCNViewã®autoenablesDefaultLightingãã©ã¡ãŒã¿ãŒã責任ãè² ããŸãã ããšã¯ãSCNViewã³ã³ããŒãã³ãã«ã·ãŒã³ãäŒããã ãã§ãã
_sceneView.scene = scene;
SceneKitã«ã¯ã«ã¡ã©å¶åŸ¡ã¡ã«ããºã ãçµã¿èŸŒãŸããŠãããallowsCameraControlãã©ã¡ãŒã¿ãŒã責任ãè² ããŸãã ãã ãããã®å Žåããªããžã§ã¯ãã®åšãã®ã«ã¡ã©ã®å転ã®æ¯å¹ ãå¶éããå¿ èŠãããããããªãã«ããå¿ èŠããããŸããã
ãªããžã§ã¯ãã®äœ¿çšäŸ
ã·ãŒã³ãªããžã§ã¯ããæäœããäŸãšããŠãã¢ãã«ã®åšãã®ãºãŒã ãšã«ã¡ã©ã®å転ã®å®è£ ãæ€èšããŸãã
è¿äŒŒ/é€å»ã®å®è£ ããå§ããŸããããããã¯ãåºæ¬çã«ã芪ãªããžã§ã¯ãã®ããŒãã«å¯ŸããŠã«ã¡ã©ããŒããZ軞ã«æ²¿ã£ãŠç§»åããããšã«ãªããŸãã SceneKitã®ãã¹ãŠã®ç§»åãå転ããºãŒã ã¯ãCoreGraphicsãšåãæ¹æ³ã§å®è¡ãããŸãã ããã¯ãSceneKitãCoreGraphicsã䜿çšããŠã¢ãã¡ãŒã·ã§ã³ãå®è£ ããŠããããã§ãã
Objective-C iOSïŒ
- (void)zoomCamera:(CGFloat) zoom{ CGFloat speedZ = 0,245; if (zoom< 1) zoom= speedZ; else if (zoom> 1) zoom= -speedZ; if (zoom< 0){ if (cameraNode.position.z < 2.5) return; } else{ if (cameraNode.position.z > 6) return; } cameraNode.transform = SCNMatrix4Translate(cameraNode.transform, 0, 0, zoom); }
Swift macOSïŒ
var allZoom: CGFloat = 0 func zoomCamera(zoom: CGFloat) { if allScrollX < 1 { let cam = ViewController.cameraRoot.childNodes[0] allZoom = zoom let speedZ = CGFloat(7) if allZoom < -speedZ { allZoom = -speedZ } else if allZoom > speedZ { allZoom = speedZ } if allZoom < 0 { if cam.position.z < 3 { return } } else { if cam.position.z > 5 { return } } cam.transform = SCNMatrix4Translate(cam.transform, 0, 0, allZoom * 0.035) } }
ãã®é¢æ°ã§ã¯ãäœãèµ·ãã£ãŠããã®ããæ£ç¢ºã«å€æããŸã-æ¥è¿ãŸãã¯é ããã-ã«ã¡ã©ã®çŸåšã®äœçœ®ãèšå®ãããå¶éå ã«åãŸãå ŽåãSCNMatrix4Translateã䜿çšããŠã«ã¡ã©ã移åããŸãã æ®ãã®ãã©ã¡ãŒã¿ãŒã¯ãããããXãYãZ軞ã«æ²¿ã£ãå€äœã§ãã macOSã§ãºãŒã ãå®è£ ããå ŽåãApple MouseãšTouchPadã®ã¹ã¯ããŒã«é床ã¯æšæºã®ã€ã³ãžã±ãŒã¿ãŒãããéãããšã«æ³šæããŠãã ãããããã«ããããºãŒã ã®æ¥µç«¯ãªå¢çã®å¶éã«éåããå¯èœæ§ããããŸãã
ã¢ãã«ã®åšãã®ã«ã¡ã©ã®å転ã®å®è£ ã¯ãè¿äŒŒã®å®è£ ãšã»ãŒåæ§ã§ãããå転ã®å Žåããã¡ãã2ã€ã®è»žãåæã«åŠçããŸãïŒã¢ãã«ã®åšããé£è¡ããY軞ãšãã¢ãã«ãäž/äžããèŠãããã®X軞ïŒ
Objective-C iOSïŒ
- (void)rotateCamera:(CGPoint) rotation{ allScrollX = rotation.x / 2; for (SCNNode *item in _sceneView.scene.rootNode.childNodes) { if (item != cameraRoot && item != cameraNode) item.transform = SCNMatrix4Rotate(item.transform, rotation.x * M_PI/180.0, 0, 0.1, 0); } if (cameraRoot.eulerAngles.x* 180.0/M_PI > 45 && rotation.y < 0){ return; } if (cameraRoot.eulerAngles.x* 180.0/M_PI < -45 && rotation.y > 0){ return; } cameraRoot.transform = SCNMatrix4Rotate(cameraRoot.transform, rotation.y * M_PI/180.0, -0.1, 0, 0); }
Swift macOSïŒ
func anglCamera(x: CGFloat, y: CGFloat) { if allZoom < 1 { allScrollX = x / 2 let cam = ViewController.cameraRoot let rootNode = ViewController.sceneRoot let dX = x * CGFloat(Double.pi / 180) for item in rootNode.childNodes { if item.name != "camera" { item.transform = SCNMatrix4Rotate(item.transform, -dX, 0, 0.1, 0) } } let angle = cam.eulerAngles let dY = y * CGFloat(Double.pi / 180) if dY < 0 { if angle.x < -1 { return } } else { if angle.x > 1 { return } } cam.transform = SCNMatrix4Rotate(cam.transform, dY, 0.1, 0, 0) } }
ããã§ã¯ãå軞ã®å転ãç¬ç«ããŠå®è¡ãããããã«ãã¢ãã«èªäœãY軞ã«æ²¿ã£ãŠå転ããŸãã å転èªäœã¯ãSCNMatrix4Rotateã«ãã£ãŠå®è£ ãããŸãã ãã®æåã®ãã©ã¡ãŒã¿ãŒã¯å€æã§ãããããã«é¢ããŠå転ãå®è¡ããã2çªç®ã®ãã©ã¡ãŒã¿ãŒã¯å転è§åºŠã§ãããä»ã®3ã€ã¯ããããXãYãZ軞ã«æ²¿ã£ãå転æåã§ãã
åé¡
ã¢ããªã±ãŒã·ã§ã³ã®æ°ããiOSããŒãžã§ã³ã«åé¡ã¯ãªãã£ããããiOSã®æå°å¿ èŠããŒãžã§ã³ã10.0ã«äžããããšãã§ããŸããã åæ§ã®ã¢ããªã±ãŒã·ã§ã³ãmacOSã«å®è£ ããå¿ èŠããã£ããšãã«ãåé¡ãå§ãŸããŸããã 10.12ããåã®macOSããŒãžã§ã³ã§ã¯ãã¢ãã«ãæäœãããšãã«ãã°ããŒãã«ãªåé¡ã«ééããŸããã
- ã¢ãã¡ãŒã·ã§ã³ã¯ç¡èŠãããŸããã
- ã¢ãã¡ãŒã·ã§ã³ã®åº§æšãã·ããããŸããã
- ã¢ãã«ãæäœããŠãããšãã«XCode IDEãã¯ã©ãã·ã¥ããå¯èœæ§ãé«ããªããŸããã
ãããã®åé¡ã¯ãŸã 解決ãããŠããŸããã macOS 10.12ã®æäœéå¿ èŠãªããŒãžã§ã³ãäžæçã«æ®ãå¿ èŠããããŸããã
ãããã«
Unity3DããiOS SDKããã³SceneKitã«ã¢ããªã±ãŒã·ã§ã³ã移æ€ããããšã«ãããã¢ããªã±ãŒã·ã§ã³ã€ã³ã¿ãŒãã§ã€ã¹ã®éçºããžã§ã¹ãã£ãŒã³ã³ãããŒã«ã®å®è£ ãç°¡çŽ åããã³é«éåã§ããŸããã äžå¿ èŠãªåªåãªãã«ãiOSããã³macOSã¢ããªã±ãŒã·ã§ã³ã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãŠãŒã¶ãŒã«æã銎æã¿ããããªããã¢ãŒã«ã€ããã¡ã€ã«ã®ãµã€ãºã¯2ã2.5åæžå°ããŸããã äžè¬ã«ã衚瀺èŠä»¶ãšåºæ¬çãªçžäºäœçšã«é¢ããŠã¯ãSceneKitã䜿çšãããšã3Dãªããžã§ã¯ããã¢ãã¡ãŒã·ã§ã³ãšææ°ã®ããŒãžã§ã³ã®macOSããã³iOSã«çµ±åããã°ããŒãã«ãªè€éãããªãããã«ã¡ã©ãšã®æãåçŽãªçžäºäœçšãå®è£ ã§ããŸããã