我想在coredata

时间:2016-06-08 13:22:14

标签: ios objective-c core-data scenekit

我有一个带灯光相机和模型的SenceKit SceneView。我也有view.allowsCameraControl = YES

我意识到当我使用它时会创建一个附加到我场景rootNode的新相机。我正在尝试捕捉相机的位置,旋转和方向,并将其存储在核心数据中。所以当再次调用项目时,这些值可以放入我放在场景中的相机中。

现在我有一个应用程序可以创建一个静态摄像机设置为SCNVectorMake3(0, -550, 900)的项目。当用户在视图中进行手势操作时,相机会启动它们可以捏合,平移和旋转,当它们单击保存在渲染中时场景并在核心数据中保存所有其他编辑,如文本和背景图像,但当然,我必须为实体添加属性以获取值。

我添加了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;
}

但是当您运行应用程序时,您要么创建一个具有相机位置默认设置的新项目,要么打开一个已经保存在核心数据中并对其进行了编辑的项目。如果我在关闭项目时不保存用户对核心数据中摄像机位置的更改,则它们将丢失并在重新打开时设置为默认值。为什么我需要使用核心数据这是否有意义?

1 个答案:

答案 0 :(得分:1)

核心数据旨在存储大量复杂数据。如果您只想存储三个花车,那么我建议您使用一些不太复杂且易于使用的东西。也许使用NSUserDefaults

如果要存储更多数据,我建议创建一个具有三个浮点值的Camera实体。然后将每个浮点数存储在正确的属性中。没有理由在Core Data中存储复杂的数据结构。核心数据已经是一个复杂的数据结构。

只需存储原始值。

  

但是当您运行应用程序时,您要么创建一个具有默认设置的新项目,要么打开一个已经对其进行过编辑的项目,因此当您创建一个新项目时,编辑将存储在核心数据中或者开始编辑另一个所有未存储在核心数据中的数据被释放,抛出。如果用户移动相机然后保存然后打开保存的项目我需要相机处于最后保存的位置和旋转。这有意义,为什么我需要使用核心数据?

不,它没有,但没关系。我确实需要了解你的持久性选择。如果您存储的不仅仅是相机位置,那么请使用Core Data。

如果您只存储 ONE 相机 ONE 引用,则核心数据过度。这是我的观点。

然而,您不需要存储复杂对象,原始问题的答案是存储三个浮点值,然后您可以在下次启动时将它们重新设置为Camera对象。