【问题标题】:I want to store pointOfView.position of allowsCameraControl in coredata [duplicate]我想将allowCameraControl的pointOfView.position存储在coredata中[重复]
【发布时间】: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


    【解决方案1】:

    Core Data 旨在存储大量复杂数据。如果您只想存储三个浮点数,那么我建议您使用一些不太复杂且更容易使用的东西。也许使用NSUserDefaults

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

    只存储原始值。

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

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

    如果您只存储 ONEONE 相机 ever 的引用,那么 Core Data 就太过分了。这就是我的观点。

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

    【讨论】:

    • 但是当您运行应用程序时,您要么创建一个具有默认设置的新项目,要么打开一个已经对其进行过编辑的项目,因为当您创建一个新项目或开始编辑另一个项目,所有未存储在 core-data 中的数据都会被释放、丢弃。如果用户移动相机然后保存然后打开保存的项目,我需要相机处于最后保存的位置和旋转。为什么我需要使用核心数据,这有意义吗?
    • 首先感谢您的帮助,Marcus 我真的很感激。我不知道我的解释是否正确,或者我只是不明白你的答案。我已经在使用 CoreData。我存储了三个实体 Project、BackgroundSettings、TextBlock。在项目下,我有五个属性,backgroundURL、dateCreated、imageURL、name 和orientation。我想我现在会为 cameraPosition 添加一个,如果我能让它工作的话,我会再添加两个 cameraRotation 和 cameraOrientation。
    • 在应用程序中,您可以创建一个新项目,当您这样做时,它会默认创建所有设置。然后,您着手更改背景图像、文本、使用的字体、文本大小和其他用户定义的选择,然后保存。现在所有的编辑都保存在核心数据中。您的所有项目都有一个列表视图,它可能是零到五十个不同的项目。如果我不使用 CoreData,如何在每个项目中获取更改后的相机位置以与该项目一起保存?这些是人们正在制作和保存以及返回以进行编辑的卡片。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 2019-09-12
    • 1970-01-01
    • 2011-01-17
    • 2014-10-11
    • 2023-01-27
    相关资源
    最近更新 更多