【发布时间】:2016-10-08 19:05:48
【问题描述】:
我有一个带有灯光相机和模型的 SenceKit SceneView。我也有view.allowsCameraControl = YES。
我意识到当我使用它时,它会创建一个连接到我场景的rootNode 的新相机。我正在尝试捕获相机的位置、旋转和方向并将其存储在核心数据中。因此,当再次调用该项目时,可以将这些值放入我放入场景中的相机中。
现在我有一个应用程序,它创建了一个静态相机设置为SCNVectorMake3(0, -550, 900) 的项目并将所有其他编辑(如文本和背景图像)保存在核心数据中,但当然,我必须为实体添加一个属性以获取 thous 值。
我添加了一个NSLog 来打印输出窗口中的位置、旋转和方向,所以我知道数据已生成并且应该可以检索。我需要一个用于相机位置、旋转和方向的变量,以及一个检查以确保它们不是 (0, 0, 0) 以及是否将它们设置为默认值 (0, -550, 900) 的方法。
对于我缺乏经验,我深表歉意,但我只是在学习 Objective-c。我已经在互联网上看到了一些弧球旋转的方法,但没有任何方法可以从 SecneKits allowsCameraControl 函数中获取值并将它们添加到相机中,这在我的情况下是一个简单的解决方案。
这是我的代码...
- (struct SCNVector3) readCameraPosition {
return SCNVector3Make(
_topScene.pointOfView.position.x,
_topScene.pointOfView.position.y,
_topScene.pointOfView.position.z);
}
- (void) update3DTextForScene: (SCNView *)view{
height3DString = 0;
view.scene = [SCNScene scene];
view.allowsCameraControl = YES;
SCNScene *scene = view.scene;
NSLog(@"Camera position: %f %f %f",
_topScene.pointOfView.position.x,
_topScene.pointOfView.position.y,
_topScene.pointOfView.position.z);
NSLog(@"Camera rotation: %f %f %f %f",
_topScene.pointOfView.rotation.x,
_topScene.pointOfView.rotation.y,
_topScene.pointOfView.rotation.z,
_topScene.pointOfView.rotation.w);
NSLog(@"Camera orientat: %f %f %f %f",
_topScene.pointOfView.orientation.x,
_topScene.pointOfView.orientation.y,
_topScene.pointOfView.orientation.z,
_topScene.pointOfView.orientation.w);
view.backgroundColor = [UIColor UIColorFromRGBAhex:0xFFFFFF00];
// camera
self.cameraNode = [SCNNode node];
self.cameraNode.camera = [SCNCamera camera];
[scene.rootNode addChildNode:self.cameraNode];
view.pointOfView = self.cameraNode;
self.cameraNode.camera.zFar = 10000;
self.cameraNode.position = SCNVector3Make(0, -550, 900);
self.cameraNode.rotation = SCNVector4Make(1.0, 0, 0, 0.588002);
self.cameraNode.orientation = SCNVector4Make(0.289784, 0, 0, 0.957092);
self.cameraNode.camera.xFov = 40;
//self.cameraNode.eulerAngles = SCNVector3Make(atan(2./3.), 0, 0);
// light
UIColor *lightColorLeft = [UIColor UIColorFromRGBhex:0xFFFFFF];
UIColor *lightColorRight = [UIColor UIColorFromRGBhex:0xFFFFFF];
_lightLeftNode = [SCNNode node];
_lightLeftNode.light = [SCNLight light];
_lightLeftNode.light.type = SCNLightTypeSpot;
_lightLeftNode.light.color = lightColorLeft;
_lightLeftNode.light.spotInnerAngle = 30;
_lightLeftNode.light.spotOuterAngle = 120;
_lightLeftNode.light.shadowRadius = 5.0;
_lightLeftNode.light.zFar = 10000;
_lightLeftNode.castsShadow = YES;
_lightLeftNode.eulerAngles = SCNVector3Make(0.6, 0, 0);
[scene.rootNode addChildNode:_lightLeftNode];
_lightRightNode = [SCNNode node];
_lightRightNode.light = [SCNLight light];
_lightRightNode.light.type = SCNLightTypeSpot;
_lightRightNode.light.color = lightColorRight;
_lightRightNode.light.spotInnerAngle = 30;
_lightRightNode.light.spotOuterAngle = 120;
_lightRightNode.light.shadowRadius = 5.0;
_lightRightNode.light.zFar = 10000;
_lightRightNode.castsShadow = YES;
_lightRightNode.eulerAngles = SCNVector3Make(0.6, 0, 0);
[scene.rootNode addChildNode:_lightRightNode];
// text
_arrayTextNodes = [NSMutableArray new];
NSString *text = [_project findBlockWithType:0].text;
NSArray *stringArray = [text componentsSeparatedByString: @"\n"];
for (NSString *string in stringArray) {
[_arrayTextNodes addObject: [self addTextNoteWithText: string view:view]];
}
CGFloat height = 0;
for (NSInteger i = 0; i < _arrayTextNodes.count; ++i) {
height += [self takeANewPositionForTextNote: _arrayTextNodes[i] withIndex: i];
}
self.lightRightNode.position = SCNVector3Make(300,
250,
600);
self.lightLeftNode.position = SCNVector3Make(-300,
250,
600);
self.lightRightNode.eulerAngles = SCNVector3Make(0.2, 0.1, 0);
self.lightLeftNode.eulerAngles = SCNVector3Make(0.2, -0.1, 0);
}
////////////////////////////////////////////////////////////////////
#pragma mark - ScreenKit
////////////////////////////////////////////////////////////////////
- (SCNNode *) addTextNoteWithText: (NSString *) text view:(SCNView *)view{
TextBlock *textBlockTopScene = [_project findBlockWithType:0];
CGFloat mainSize = textBlockTopScene? [textBlockTopScene.size integerValue] * 3 : 90;
SCNText *sceneText = [SCNText textWithString:text extrusionDepth: textBlockTopScene? [textBlockTopScene.depth doubleValue] : mainSize / 3. ];
sceneText.chamferRadius = MIN(sceneText.extrusionDepth / 5., 5); // first way
sceneText.font = textBlockTopScene?
[UIFont fontWithName:textBlockTopScene.font size: mainSize] :
[UIFont fontWithName:@"HelveticaNeue-Medium" size: mainSize];
sceneText.alignmentMode = kCAAlignmentCenter;
sceneText.wrapped = YES;
SCNNode *textNode = [SCNNode nodeWithGeometry:sceneText];
SCNMaterial *material1 = [SCNMaterial new];
material1.diffuse.contents = [UIColor UIColorFromRGBhex: textBlockTopScene? [textBlockTopScene.color integerValue] : 0];
UIColor * specularColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"noise"]];
material1.specular.contents = [specularColor offsetWithHue:0 saturation:0 lightness: textBlockTopScene? [textBlockTopScene.specular doubleValue] : 0.5 alpha:0];
textNode.geometry.materials = @[material1];
[view.scene.rootNode addChildNode:textNode];
return textNode;
}
- (CGFloat) takeANewPositionForTextNote: (SCNNode *) textNode withIndex: (NSInteger) index{
SCNVector3 v1 = SCNVector3Make(0,0,0);
SCNVector3 v2 = SCNVector3Make(0,0,0);
[textNode getBoundingBoxMin:&v1 max:&v2];
NSInteger count = _arrayTextNodes.count;
CGFloat dx = (v1.x - v2.x) / 2.0;
CGFloat dy = (v1.y - v2.y) / 2.0;
if (!height3DString) {
height3DString = dy;
}
textNode.position = SCNVector3Make(dx,
height3DString * ((count + index * 2.5) - (count - 1) * 2.5),
0);
return dy * 1.25;
}
但是,当您运行该应用程序时,您要么创建一个具有默认相机位置设置的新项目,要么打开一个已保存在核心数据中并对其进行编辑的项目。如果我在关闭项目时不保存用户对核心数据中相机位置的更改,他们将丢失并在重新打开项目时设置为默认值。为什么我需要使用核心数据这有意义吗?
【问题讨论】:
标签: ios objective-c core-data scenekit