Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the sphere to add buttons or views at a specific point in the photo. #25

Open
leo1mml opened this issue May 20, 2018 · 24 comments
Open

Comments

@leo1mml
Copy link

leo1mml commented May 20, 2018

I was wondering if I could make use of buttons or something like this to go through doors in a photo for example. Is it possible?

@OlegPanfyorov
Copy link

Same question from me

@yakovlev0509
Copy link

I have the same question, currently trying to figure out how to place something on the sphere and add tap even to it.
"to go through doors in a photo". -- is my main goal.

@elibendavid
Copy link

'Hotspots' functionality would definitely boost this project way up

@yakovlev0509
Copy link

yakovlev0509 commented Apr 8, 2019

@elibendavid @OlegPanfyorov @leo1mml
I was required to add hotspots to panoramas of the interior, to simulate navigation in the apartments.

For this, I added CTPanoramaView as files, and after it, I worked with SKScene object, this solution provides two objects in SKScene: sphere/cylinder and camera objects.
You can easily add your own object(SKNode) within sphere/cylinder with these positions (x: from -5 to 5; y: from -5 to 5; z: from -5 to 5) and detect a tap on it.
Using tag or name parameters you can detect which of the object was tapped and do some required actions. In my case, I change panorama photos and reload new hot spots for this panorama.

After I find this ability it saves a huge amount of time for me.

@elibendavid
Copy link

elibendavid commented Apr 8, 2019

@yakovlev0509

Wow! Sounds good.
Would be great if you can share some code

Thanks!

@yakovlev0509
Copy link

@elibendavid

You need to read more info about SKScene and SKNode.

As you found in CTPanoramaView source code, it generates a SKScene with 2 objects in it:
sphere/cylinder -- an object which applies to itself your panorama image
and camera objects -- actually a camera object.

In my case, I worked with the sphere. As you can find sphere have coordinates (x: from -5 to 5; y: from -5 to 5; z: from -5 to 5) on the SKScene
So creating and adding any SKNode objects within this range will add an object in your sphere.
And of course, you will need to adjust the angle for a created object so it will always look to the Camera object side. (this code can be easily found in StackOverflow), their texture, etc.
In my case, I just used Plain SKNode objects and added a tag to them, so I can detect which of them was tapped. Because touch will also detect a sphere object (as it is SKNode object).
Check Raywenderlich post about detecting objects from CameraNode in SKScene.

They're not so much code need to be added. If you will check CTPanoramaView code in more details you will understand how and where to place it. And creating SKNode object is a very easy task.

Please let me know if you will have any questions.

@elibendavid
Copy link

elibendavid commented Apr 11, 2019

@yakovlev0509

Thanks!
Eventually, your inspiration was enough :), we got it working.

@SulimanHussain
Copy link

@elibendavid @OlegPanfyorov @leo1mml
I was required to add hotspots to panoramas of the interior, to simulate navigation in the apartments.

For this, I added CTPanoramaView as files, and after it, I worked with SKScene object, this solution provides two objects in SKScene: sphere/cylinder and camera objects.
You can easily add your own object(SKNode) within sphere/cylinder with these positions (x: from -5 to 5; y: from -5 to 5; z: from -5 to 5) and detect a tap on it.
Using tag or name parameters you can detect which of the object was tapped and do some required actions. In my case, I change panorama photos and reload new hot spots for this panorama.

After I find this ability it saves a huge amount of time for me.

Hello! Can you help me with some code sample. I have actually added nodes successfully but the nodes are not showing in the way i want. How can I add for example a small car image as node which will supposed to be tappable. Any Help......Thanks

@KamaNext
Copy link

@elibendavid

Вам нужно прочитать больше информации о SKScene и SKNode.

Как вы обнаружили в исходном коде CTPanoramaView, он генерирует SKScene с двумя объектами в нем: сфера/цилиндр - объект, который применяет к себе ваше панорамное изображение и объекты камеры - на самом деле объект камеры.

В моем случае я работал со сферой. Поскольку вы можете найти сферу с координатами (x: от -5 до 5; y: от -5 до 5; z: от -5 до 5) на SKScene, поэтому создание и добавление любых объектов SKNode в этом диапазоне добавит объект в ваша сфера. И, конечно же, вам нужно будет настроить угол созданного объекта, чтобы он всегда смотрел в сторону объекта камеры. (этот код легко найти в StackOverflow), их текстуру и т. д. В моем случае я просто использовал объекты Plain SKNode и добавил к ним тег, чтобы я мог определить, какой из них был нажат. Потому что касание также обнаружит объект сферы (поскольку это объект SKNode). Проверьте сообщение Raywenderlich об обнаружении объектов из CameraNode в SKScene.

Они не так много кода нужно добавить. Если вы более подробно изучите код CTPanoramaView, то поймете, как и где его размещать. А создание объекта SKNode — очень простая задача.

Пожалуйста, дайте мне знать, если у вас возникнут вопросы.

friend tell me please screenshots how you did it or share the code

@KamaNext
Copy link

@elibendavid

Вам нужно прочитать больше информации о SKScene и SKNode.

Как вы обнаружили в исходном коде CTPanoramaView, он генерирует SKScene с двумя объектами в нем: сфера/цилиндр — объект, который применяет к себе ваше панорамное изображение и объекты камеры — на самом деле объект камеры.

В моем случае я работал со сферой. Поскольку вы можете найти сферу с координатами (x: от -5 до 5; y: от -5 до 5; z: от -5 до 5) на SKScene, поэтому создание и добавление любых объектов SKNode в этом диапазоне добавит объект в ваша сфера. И, конечно же, вам нужно будет настроить угол созданного объекта, чтобы он всегда смотрел в сторону объекта камеры. (этот код легко найти в StackOverflow), их текстуру и т. д. В моем случае я просто использовал объекты Plain SKNode и добавил к ним тег, чтобы я мог определить, какой из них был нажат. Потому что касание также обнаружит объект сферы (поскольку это объект SKNode). Проверьте сообщение Raywenderlich об обнаружении объектов из CameraNode в SKScene.

Они не так много кода нужно добавить. Если вы более подробно изучите код CTPanoramaView, то поймете, как и где его размещать. А создание объекта SKNode — очень простая задача.

Пожалуйста, дайте мне знать, если у вас возникнут вопросы.

Друг можешь дать пожалуйста образец кода,
как ты добавил несколько изображений

@yakovlev0509
Copy link

@KamaNext Please check the comments above:

Here is info about SKNode:
https://developer.apple.com/documentation/spritekit/sknode
There should be a huge amount of example code on the internet.

I don't have the project source code with me, but you can ask if you have specific questions.
And please also follow this advice from my previous comment: "You need to read more info about SKScene and SKNode."
It should be a quick task when you understand how it works.

@yakovlev0509
Copy link

@SulimanHussain

Please check Raywenderlich post about detecting objects from CameraNode in SKScene(in case if you need to detect taps on the SKNode object). Also, they described how to add image to SKNode, and how to make images of SKNode always follow the camera object.

@KamaNext
Copy link

KamaNext commented Oct 28, 2023

@yakovlev0509 Please check the comments above:

Here is info about SKNode: https://developer.apple.com/documentation/spritekit/sknode There should be a huge amount of example code on the internet.

I don't have the project source code with me, but you can ask if you have specific questions. And please also follow this advice from my previous comment: "You need to read more info about SKScene and SKNode." It should be a quick task when you understand how it works.

I'm trying to add points, but it doesn't work out, could you make a small example, if you don't mind, or help me figure it out, I would thank you

@yakovlev0509
Copy link

@yakovlev0509 Please check the comments above:

Here is info about SKNode: https://developer.apple.com/documentation/spritekit/sknode There should be a huge amount of example code on the internet.
I don't have the project source code with me, but you can ask if you have specific questions. And please also follow this advice from my previous comment: "You need to read more info about SKScene and SKNode." It should be a quick task when you understand how it works.

I'm trying to add points, but it doesn't work out, could you make a small example, if you don't mind, or help me figure it out, I would thank you

@KamaNext please post here the code part related to this, maybe something wrong with it.

@KamaNext
Copy link

KamaNext commented Nov 1, 2023

@yakovlev0509
class MarkPoinScene: SKScene {
override init() {
let markPoint = SKSpriteNode(imageNamed: "mark")
markPoint.name = "markP"
super.init()

addChild(markPoint)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func moveMark(){
let markP = childNode(withName: "markP")
}
}
var anchorPoint: CGPoint = CGPoint( x: 0.5, y: 0.5)
{
didSet
{
let translateX = ( anchorPoint.x - 0.5 )
let translateY = ( anchorPoint.y - 0.5 )
let translateZ = ( anchorPoint.y - 0.5 )
}
}

Artem If you don’t mind, you can download the CTPanorama library and add 1 point
I think I can understand by looking at your code

@yakovlev0509
Copy link

yakovlev0509 commented Nov 2, 2023

@KamaNext try something like this:

//your CTPanoramaView
var panoramaWalkView: CTPanoramaView  

//setup child node
let material = SCNMaterial()
material.diffuse.contents = UIImage(named: spot["yourNodeImageName"]!)
material.isDoubleSided = true // Optional
                    
let planeGeometry = SCNPlane(width: 0.4,height: 0.7)
planeGeometry.materials = [material]
let routNode = SCNNode(geometry: planeGeometry)

routNode.position = SCNVector3(x,y,z) // Place your node in space
routNode.name = "Spot" // Better to have as later you can sort or work with them by their names
routNode.look(at: panoramaWalkView.cameraNode.position) // Make your node look always at camera object
spotsArray.append(routNode) // Optional
panoramaWalkView.scene.rootNode.addChildNode(routNode) // Here we add node to Panorama view

Later, you can access your child nodes via:

panoramaWalkView.scene.rootNode.enumerateChildNodes { (node, stop) in ...

To handle taps or actions on your nodes, you can use something like this:

  1. Add gesture recognizer to PanoramaView
  2. And use:
let tapLocation = sender.location(in: panoramaWalkView?.sceneView)
let hitTestResults = panoramaWalkView?.sceneView.hitTest(tapLocation)
        
let node = hitTestResults!.first?.node // Your tapped by user Node

It is not the best implementation or solution. But I hope it helps you solve your task/goal.

@KamaNext
Copy link

KamaNext commented Nov 5, 2023

@KamaNext try something like this:

//your CTPanoramaView
var panoramaWalkView: CTPanoramaView  

//setup child node
let material = SCNMaterial()
material.diffuse.contents = UIImage(named: spot["yourNodeImageName"]!)
material.isDoubleSided = true // Optional
                    
let planeGeometry = SCNPlane(width: 0.4,height: 0.7)
planeGeometry.materials = [material]
let routNode = SCNNode(geometry: planeGeometry)

routNode.position = SCNVector3(x,y,z) // Place your node in space
routNode.name = "Spot" // Better to have as later you can sort or work with them by their names
routNode.look(at: panoramaWalkView.cameraNode.position) // Make your node look always at camera object
spotsArray.append(routNode) // Optional
panoramaWalkView.scene.rootNode.addChildNode(routNode) // Here we add node to Panorama view

Later, you can access your child nodes via:

panoramaWalkView.scene.rootNode.enumerateChildNodes { (node, stop) in ...

To handle taps or actions on your nodes, you can use something like this:

  1. Add gesture recognizer to PanoramaView
  2. And use:
let tapLocation = sender.location(in: panoramaWalkView?.sceneView)
let hitTestResults = panoramaWalkView?.sceneView.hitTest(tapLocation)
        
let node = hitTestResults!.first?.node // Your tapped by user Node

It is not the best implementation or solution. But I hope it helps you solve your task/goal.
@yakovlev0509
Friend, thank you very much for trying to help me, I really appreciate it and would like to thank you. Unfortunately, I still have problems with adding hotspots, I didn't have these problems in JavaScript and somehow it turned out easily, Swift is still a little unclear in terms of Object-Oriented Programming. If you could download the sources of CTPanoramaView and add 1 point, it would make me happy.

@KamaNext
Copy link

@yakovlev0509
Friend, please help me, I can't add an object in any way, I'm trying to use your instructions and I get errors

@yakovlev0509
Copy link

@KamaNext

Friend, please help me, I can't add an object in any way, I'm trying to use your instructions and I get errors

Please share more info

@KamaNext
Copy link

KamaNext commented Nov 19, 2023

@yakovlev0509
@objc public class BetterOnboardingScene: SKScene{
override public init() {
let markSpriteView = SKSpriteNode(imageNamed: "mark")
markSpriteView.name = "markPoint"
let material = SCNMaterial()
material.isDoubleSided = true // Optional
let planeGeometry = SCNPlane(width: 0.4,height: 0.7)
planeGeometry.materials = [material]
let routNode = SCNNode(geometry: planeGeometry)
routNode.position = SCNVector3(1,1,1) // Place your node in space
routNode.name = markSpriteView.cameraNode.position)
spotsArray.append(routNode) // Optional
markSpriteView.scene.rootNode.addChildNode(routNode)
super.init()
addChild(markSpriteView)
}

eror ( Value of type 'SKSpriteNode' has no member 'cameraNode' )
eror (Value of type 'SKScene?' has no member 'rootNode')

@KamaNext
Copy link

@yakovlev0509
please download the panorama project and add 1 point, I will thank you

@KamaNext
Copy link

@yakovlev0509
@objc public class markSpriteView: SKScene{
public override func didMove(to view: SKView) {
let markSpriteView = SKNode()
markSpriteView.name = "markPoint"
let markPoint = SKSpriteNode(imageNamed: "mark")
let material = SCNMaterial()
material.isDoubleSided = true // Optional
let planeGeometry = SCNPlane(width: 0.4,height: 0.7)
planeGeometry.materials = [material]
let routNode = SCNNode(geometry: planeGeometry)
routNode.position = SCNVector3(1,1,1)
routNode.name = "Spot"
self.addChild(markSpriteView)
}
is this true?

@KamaNext
Copy link

@yakovlev0509
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}

public override init(frame: CGRect) {
    super.init(frame: frame)
    commonInit()
}
eror (Property 'self.MarkSpriteView' not initialized at super.init call)

@yakovlev0509
Copy link

@yakovlev0509 public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() }

public override init(frame: CGRect) {
    super.init(frame: frame)
    commonInit()
}
eror (Property 'self.MarkSpriteView' not initialized at super.init call)

@KamaNext your error totally not related to CTPanoramaView. This is not suitable for this Issue thread. Please post a question in Stackoverflow.

You have some MarkSpriteView (naming - would be better to "markSriteView"), which should be initialized during init, and you are not doing this.
First Google/Stackoverflow link will explain in details why this happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants