Swift SceneKit - I am trying to figure out if a Node object goes off the screen - ios

Using SceneKit
I want to make the gray transparent box to disappear and only show the colored boxes when the user zooms in.
So I want to detect when that box's edges are starting to fall off the screen as I zoom, so I can hide the gray box accordingly.

First thoughts, but there may be better solutions:
You could do an unprojectPoint on the node and check against screen coordinates, do the +/- math on object size and skip Z. I "think" that would work
You can do some physics based collision detection against an invisible box or plane geometries that acts as your screen edges, has some complexity if your view is changing, but testing would be easy - just leave visible until you get what you want, then isVisible=false
isNode(insideFrustomof: ) - returns boolean on whether it "might" be visible. I'm assuming "might" means obscured by other geometry which in your case, shouldn't matter (edit) on second thought, that doesn't solve your problem but I'll leave it in here for reference.

Related

How can I get boxes to snap into position when I drag and drop them into certain regions of the screen?

I am currently building a game on swift, using Storyboards. The game revolves around generating income from fishing lobsters. Users have lobster pots, which they can place into either inshore or outshone regions of the water. With no prior experience. I have minimal knowledge on how to code in swift.
My problem at the moment is understanding collision detection. There are three regions of the screen where the users can drag their pots into. The first screen is the starting position of the lobster pots, from which the player must drag the pots into either inshore or offshore locations. Currently, I have managed to code the action of dragging and dropping the pots, so they can be placed into any point on the screen. What I hope to do is to be able to have the pots to snap into position when the pots are dropped within the regions of either the inshore of offshore boxes. Furthermore, when the pots are dropped into place, I would like them to be organized in a row, equally spaced, and dropping into a row below, filling up the box.
Image -
I think I should also mention that the background is an image view, taken as a screenshot of the view when the game is running. I did this to avoid layering, as some pots would sometimes move behind the boxes when dragging them.
Thanks in advance.
Here some ideas:
You already have the code to move the tiles, that's good. All you now need is same math.
Although your background is an image, you also need some data model to keep, where your stuff is (or where your pots belong to). It is important to know, if a pot is in "My Pots" or "Inshor" or "Outshore". This information has to keep in some objects, like "myPots" and "inshore" and so on.
So dragging doesn't only move the pots on screen, it also changes where a pot belong to.
Hint: A representation of a area (myPots, ...) can be done with invisible areas. Invisible, because you already have the background. But a invisible rectangle gives you the ability to resize the ui without complicated re-calculations.
I would devide the area like this:
The coordinates are just examples for better understanding.
Most game engines work with coordinate (0,0) at top left.
So if you drag and release a pot, you have to calculate the end point of drag and compare it with your areas. No complicated collision detection necessary, because you only test if a point is in an area. But if you want collision detection, search for AABB collision detection (like here https://studiofreya.com/3d-math-and-physics/simple-aabb-vs-aabb-collision-detection/).
In your case it would be enough to have the decision:
if draggedPot.endCoordinate.y > 100 {
// in or out shore
if draggedPot.endCoordinate.x > 300 {
// outshore
}
else {
// inshore
}
}
else {
// still in myPots
}
I hope you get the idea :)
For arrange in a row it's also some math. Loop over the pots in an area, place one by one, always start-x + width-of-pot + some space. If this is greater than width of the area, set y to height of pot + some space and x starts at zero.

Interact with complex figure in iOS

I need to be able to interact with a representation of a cilinder that has many different parts in it. When the users taps over on of the small rectangles, I need to display a popover related to the specific piece (form).
The next image demonstrates a realistic 3d approach. But, I repeat, I need to solve the problem, the 3d is NOT required (would be really cool though). A representation that complies the functional needs will suffice.
The info about the parts to make the drawing comes from an API (size, position, etc)
I dont need it to be realistic really. The simplest aproximation would be to show a cilinder in a 2d representation, like a rectangle made out of interactable small rectangles.
So, as I mentioned, I think there are (as I see it) two opposite approaches: Realistic or Simplified
Is there a way to achieve a nice solution in the middle? What libraries, components, frameworks that I should look into?
My research has led me to SceneKit, but I still dont know if I will be able to interact with it. Interaction is a very important part as I need to display a popover when the user taps on any small rectangle over the cylinder.
Thanks
You don't need any special frameworks to achieve an interaction like this. This effect can be achieved with standard UIKit and UIView and a little trigonometry. You can actually draw exactly your example image using 2D math and drawing. My answer is not an exact formula but involves thinking about how the shapes are defined and break the problem down into manageable steps.
A cylinder can be defined by two offset circles representing the end pieces, connected at their radii. I will use an orthographic projection meaning the cylinder doesn't appear smaller as the depth extends into the background (but you could adapt to perspective if needed). You could draw this with CoreGraphics in a UIView drawRect.
A square slice represents an angle piece of the circle, offset by an amount smaller than the length of the cylinder, but in the same direction, as in the following diagram (sorry for imprecise drawing).
This square slice you are interested in is the area outlined in solid red, outside the radius of the first circle, and inside the radius of the imaginary second circle (which is just offset from the first circle by whatever length you want the slice).
To draw this area you simply need to draw a path of the outline of each arc and connect the endpoints.
To check if a touch is inside one of these square slices:
Check if the touch point is between angle a from the origin at a.
Check if the touch point is outside the radius of the inside circle.
Check if the touch point is inside the radius of the outside circle. (Note what this means if the circles are more than a radius apart.)
To find a point to display the popover you could average the end points on the slice or find the middle angle between the two edges and offset by half the distance.
Theoretically, doing this in Scene Kit with either SpriteKit or UIKit Popovers is ideal.
However Scene Kit (and Sprite Kit) seem to be in a state of flux wherein nobody from Apple is communicating with users about the raft of issues folks are currently having with both. From relatively stable and performant Sprite Kit in iOS 8.4 to a lot of lost performance in iOS 9 seems common. Scene Kit simply doesn't seem finished, and the documentation and community are both nearly non-existent as a result.
That being said... the theory is this:
Material IDs are what's used in traditional 3D apps to define areas of an object that have different materials. Somehow these Material IDs are called "elements" in SceneKit. I haven't been able to find much more about this.
It should be possible to detect the "element" that's underneath a touch on an object, and respond accordingly. You should even be able to change the state/nature of the material on that element to indicate it's the currently selected.
When wanting a smooth, well rounded cylinder as per your example, start with a cylinder that's made of only enough segments to describe/define the material IDs you need for your "rectangular" sections to be touched.
Later you can add a smoothing operation to the cylinder to make it round, and all the extra smoothing geometry in each quadrant of unique material ID should be responsive, regardless of how you add this extra detail to smooth the presentation of the cylinder.
Idea for the "Simplified" version:
if this representation is okey, you can use a UICollectionView.
Each cell can have a defined size thanks to
collectionView:layout:sizeForItemAtIndexPath:
Then each cell of the collection could be a small rectangle representing a
touchable part of the cylinder.
and using
collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
To get the touch.
This will help you to display the popover at the right place:
CGRect rect = [collectionView layoutAttributesForItemAtIndexPath:indexPath].frame;
Finally, you can choose the appropriate popover (if the app has to work on iPhone) here:
https://www.cocoacontrols.com/search?q=popover
Not perfect, but i think this is efficient!
Yes, SceneKit.
When user perform a touch event, that mean you knew the 2D coordinate on screen, so your only decision is to popover a view or not, even a 3D model is not exist.
First, we can logically split the requirement into two pieces, determine the touching segment, showing right "color" in each segment.
I think the use of 3D model is to determine which piece of data to show in your case if I don't get you wrong. In that case, the SCNView's hit test method will do most of work for you. What you should do is to perform a hit test, take out the hit node and the hit's local 3D coordinate of this node, you can then calculate which segment is hit by this touch and do the decision.
Now how to draw the surface of the cylinder would be the only left question, right? There are various ways to do, for example simply paint each image you need and programmatically and attach it to the cylinder's material or have your image files on disk and use as material for the cylinder ...
I think the problem would be basically solved.

iOS Triangular Image view

so I'm making a game and pretty much when the player (which is a triangular shaped rocket) hits an object flying at you (a rock) the game ends. I have everything working well but my problem is the rocket is a triangle yet the image view its in is a rectangle. So if the edge of the image view touches the rock the game will end even though the actual rocket didn't touch the object. So basically how can I make the rock image view not recognize the parts of the rocket image view which are empty? Basically a triangular shaped image view.
Thank you for your help. Let me know if you need more info or want to see the code I have for them to collide.
You analytically present the triangle with 3 points and a rock with a center and radius then find and implement an algorithm checking a hit test between those 2 shapes. Or draw the two shapes onto some graphics context using an appropriate blending and check for overlapping pixels (for instance draw one as red and another as green and look if a pixel that is both red and green exists) you could actually do that with 2 image views having those colors and .5f alpha added on the 3rd invisible view but you would need to get the image from the view and then iterate through all the pixels. In any of the cases do this check only after the corresponding view frames overlap.

iOS Maps - Grid Overlay

I'm looking for a way to overlay the iOS maps with a grid. The complete earth needs to be divided into squares. The location of the user doesn't effect the placement of the squares (In other words; the squares are always placed the same. On every iPhone, no matter where the user is).
I Looked into MKOverlay, but I've never used this so it's very new to me. Also, when zooming in/out should effect the overlay. It's very important that the squares are always covering the same area on the map (For example; A square should be 100mx100m in real world, when you zoom out, the square should cover the same 100x100).
Is there anybody that can point me in the right direction?
Is it possible to draw the grid from een .xml? Example given; On .XML is holding all squares with their coordinates on the map. When the user loads the map, the 100 squares around the user are loaded.

Show popup window for visible spots on globe

I have a globe, similar to http://mrdoob.github.com/three.js/examples/webgl_trackballcamera_earth.html.
My globe has some spots on different locations (f.ex. Paris, Rome or London). Whenever one of these spots come into view, a popup window with additional information to that location should popup appear, and again disappears when that spot rotates out of view, quite similar to http://workshop.chromeexperiments.com/cloudglobe/.
You need 3D coordinates of those points and you need to transform(rotate or whatever) them with globe. Then use this code http://www.opengl.org/wiki/GluProject_and_gluUnProject_code to get screen space coordinates of those points. After that it is simple question of HTML, CSS and some javascript. You know where they are on screen so, for example, you can put some absolute positioned divs with text. But you will need to check on which side of globe those spots are - use rotation phase of the sphere or z-coordinate of the point or simple do color-based picking to see if this spot is visible.

Resources