Big SCNGeometry SceneKit for iOS - scenekit

I am working on a cocoa/iOS projet.
I have a common swift class which manage a Scenekit scene.
I want to draw a big terrain (about 5000x5000 points).
I have 2 triangles per 4 points. I have created a scngeometry object for the whole terrain (is it a good thing ?)
I decided to store those points in a 6-Float structure (x,y,z and r,g,b). I tried to create an empty array or to allocate a big array at the begining : i got the same issue.
I work with Int datatype for indices array.
The project works fine on Cocoa but i get memory errors on iOS. I think this is because of the need to have a big and contigous array for vertex.
I tried to create several chunks of geometry objects but scene kit does not like if we erase a previous buffer.
What is the best practice in this case ?
Is there a way to store vertex on the mass storage instead of memory arrays/buffers ?
Thanks

So...twice as many terrain points as there are pixels on a shiny new 5K display? That's a huge amount of memory to be using at once on iOS. And you won't be able to see that resolution on an iOS device.
So how about:
Break your 25 million pixel terrain into smaller tiles, each in its own SCNNode. Loop through the tiles, create one SCNNode, throw away the 6-Float array for that tile and move to the next.
Use SCNLevelOfDetail to produce much simpler versions of those nodes, for display when they're very far away.
Do the construction work on OS X. Archive your scene (NSSecureCoding). Bundle that scene into the iOS app.
Consider using reference nodes in your main SCNScene, and archive each tile as a separate SCNScene file.
Hopefully you're already using triangle strips, not triangles, to build your geometry.

Related

replacing CALayer arrays with CAMetalLayer arrays

I have a painting app which at any given time interactively shows content from an array of 200 or so CALayers via an UIImageView. I get reasonable performance, but I'm wondering if there could be any performance benefits with using CAMetalLayers instead. In particular, I'm curious if I could benefit from blitting textures directly to each CAMetalLayer, and would there be any hardware considerations with stacking/displaying so many CAMetalLayers at once.
Are there any gotchas I should consider before implementing, and should I continue using an UIImageView (or other) to host these newly Metal-backed sublayers? Any thoughts would be appreciated.
That’s not going to work. You should be keeping track of your stroke’s data. For example an array of points would be a single stroke and then you should have an array of those strokes. It could be only points (x, y) or more probably also containing color, size and other variables. You should know what do you need to describe your stroke.
Then use that to draw (stamp at those locations). When you want to undo, just start drawing from the beginning all the strokes in the array until n-1, n-2, etc...

Swift 3 - Function to create n number of sprites with random x/y coordinates

I am trying to create multiple SKSpriteNodes that each have their own independent variables that I can change/modify. I would like to be able to run a function when the app starts, for example "createSprites(5)" which would create 5 sprites with the image/texture "shape.png" at random x and y coordinates and add all 5 Sprites to an array that I can access and edit different Sprite's positioning based on the index value. I would then like to be able to have another function "addSprite()" which, each time it is called, create a new Sprite with the same "shape.png" texture, place it at another random X and Y coordinate and also add it to the array of all Sprites to, again, be able to access later and change coordinates etc.
I have been looking through so many other Stack Overflow pages and can not seem to find a solution. My ideal solution would simply be the two functions I stated earlier. One to create an "n" number of Sprites and another function to create and add one more sprite to the array each time it is called.
Hope that makes sense, I'm fairly new to Swift and all this Sprite stuff, so simple informative answers would be very much appreciated.
You're not going to find an ideal solution from the past because nobody has likely had exactly the same desire with both Swift and SpriteKit. Having said that, there's likely partial answers you can blend together, and get the result you want or, at least, an understanding of how to do it.
Sprite Positioning in SK is probably the first thing to read up on:
https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html
having gotten that figured out, you can move to random positions.
Random positioning of Sprites:
Duplicate Sprite in Random Positions with SpriteKit
Sprite Kit random positions
Both use earlier versions of randomisation that aren't as powerful as what's available now, in GameplayKit. So... Generating random numbers in Swift with GameplayKit:
https://www.hackingwithswift.com/read/35/overview
It's hard to overstate the importance of understanding the various possibilities of game design implications of varying types of randomisation, so probably wise to read this, from Apple:
https://developer.apple.com/library/content/documentation/General/Conceptual/GameplayKit_Guide/RandomSources.html
After that, it's a case of needing to determine what constitutes a time or event at which to create more sprites at more random positions, and how fussy you want to be about proximity to other sprites, and overlaps.

Simple Multi-Blob Detection of a Binary Image?

If there is a given 2d array of an image, where threshold has been done and now is in binary information.
Is there any particular way to process this image to that I get multiple blob's coordinates on the image?
I can't use openCV because this process needs to run simultaneously on 10+ simulated robots on a custom simulator in C.
I need the blobs xy coordinates, but first I need to find those multiple blobs first.
Simplest criteria of pixel group size should be enough. But I don't have any clue how to start the coding.
PS: Single blob should be no problem. Problem is multiple blobs.
Just a head start ?
Have a look at QuickBlob which is a small, standalone C library that sounds perfectly suited for your needs.
QuickBlob comes with a small command-line tool (csv-blobs) that outputs the position and size of each blob found within the input image:
./csv-blobs white image.png
X,Y,size,color
28.37,10.90,41,white
51.64,10.36,42,white
...
Here's an example (output image is produced thanks to the show-blobs.py tiny Python utility that comes with QuickBlob):
You can go through the binary image labeling the connected parts with an algorithm like the following:
Create a 2D array of ints, labelArray, that will hold the labels of the connected regions and initiate it to all zeros.
Iterate over each binary pixel, p, row by row
A. If p is true and the corresponding value for this position in the labelArray is 0 (unlabeled), assign it to a new label and do a breadth-first search that will add all surrounding binary pixels that are also true to that same label.
The only issue now is if you have multiple blobs that are touching each other. Because you know the size of the blobs, you should be able to figure out how many blobs are in a given connected region. This is the tricky part. You can try doing a k-means clustering at this point. You can also try other methods like using binary dilation.
I know that I am very late to the party, but I am just adding this for the benefipeople who are researching this problem.
Here is a nice description that might fit your needs.
http://www.mcs.csueastbay.edu/~grewe/CS6825/Mat/BinaryImageProcessing/BlobDetection.htm

How do load an image into a 2D array element?

I'm currently doing my A-Level Computing project for which I am making my own version of the classic game Space Invaders.
To create the wave of space invaders I want to use a 2D array of images, where the images are loaded from a disk and then displayed on the form but I am unsure of how load the images into the array and then display the array on a form.
The current arrays are:
ImagePaths:array [1..3] of string =('SpaceInvader1.jpg', 'SpaceInvader2.jpg', 'SpaceInvader3.jpg');
Wave:array[1..11, 1..5] of TImage; x,y:integer;
What I would like to know is: how would I load an image into an array element? eg how would I load 'SpaceInvader1.jpg' to array element [1,1]?
Any help would be greatly appreciated.
If you're going to be coding graphical animations, you probably won't want to do it directly on the form. Trying to move things around can be tricky, especially if you want to animate smoothly and not get a lot of flicker and graphical artifacts.
It would be better to use a rendering library. The workflow goes like this:
Create a rendering context on the form. This is a control that provides a surface for graphical animations to run on.
Load your three images into memory.
Create an array of objects to represent the game data associated with your monsters. (Position, movement direction and speed, etc.) It can be flat or 2D, whichever works better for you.
Set up a render loop that goes like this:
For each monster in the array, draw it at its position.
Draw the player's ship and all projectiles.
Check for collisions and handle appropriately.
Check for player input and handle appropriately.
You can find plenty of information on rendering libraries for Delphi in the forums at Pascal Game Development.
You have the following declarations:
ImagePaths:array [1..3] of string =(
'SpaceInvader1.jpg',
'SpaceInvader2.jpg',
'SpaceInvader3.jpg'
);
Wave: array[1..11, 1..5] of TImage;
You want to know how to populate the array of images. It is quite wasteful to create 55 images when 3 will suffice. So instead of that, use indirection. Store references to the images. And TImage is a visual component, and so not appropriate for a sprite.
I would hold the images in an array like this:
Sprites: array [1..3] of TBitmap;
And populate it
JPEGImage := TJPEGImage.Create;
try
for i := 1 to 3 do
begin
JPEGImage.LoadFromFile(ImagePaths[i]);
Sprites[i] := TBitmap.Create;
Sprites[i].Assign(JPEGImage);
end;
finally
JPEGImage.Free;
end;
Then populate your Wave array like this, for example:
Wave: array[1..11, 1..5] of TBitmap;
....
for i := 1 to 11 do
for j := 1 to 5 do
Wave[i,j] := Sprites[1];// or whichever sprite you want
Of course your sprites may be better with a real name rather than in an array.
Some other comments:
JPEG is a bad format for a game sprite. It is a lossy format. A plain Windows bitmap would be fine, as would a GIF or PNG.
I'd much rather see the images as embedded resources. Then your executable can stand alone.
I'd also far rather see your Waves array holding the state of each invader. And then you would create a function that would render that state onto a canvas.

Tile based game theory

I'm looking for articles on tile based games, like the old ultima 6&7, or even puzzle pirates. Specifically:
How they keep track of objects on the map. Objects such as other characters, or trees, or things the character can move.
AI behind the characters. How the game handles character behavior for
characters on the map that are off screen. Especially with very large maps and numerous characters.
I remember checking out Amit's Game Development page back when I wrote some games. He has a great sub-section on tiles that has most of what you want.
You could look through back issues of Game Developer magazine to see if something addresses what you're asking in detail.
For (1) the easiest way of dealing with a tile-based map where each tile can contain multiple objects is to just have a big multidimensional array of structs representing each tile. The struct contains a pointer to the head of a linked list representing all the objects in that tile. This is very memory efficient and lets you quickly find everything in a certain tile while also enumerating them along some other axis (eg, owner, allocation arena, etc).
RogueBasin is devoted to Rogue-like games (e.g. Rogue, NetHack, ). All of those games were based on a simple square grid. The site has an extensive section on developing games like that: http://roguebasin.roguelikedevelopment.org/index.php?title=Articles
You will find both suggestions and code there which could be used to build a game like you describe. After all, the only real difference between Rogue/Larn/NetHack/etc. and Diablo or the Ultima series is using simple text characters to depict the map and gameplay vs. isometric sprites.
In particular you will find information about calculating the area illuminated by a torch or lantern the user is carrying, data structures for storing maps, algorithms for automatic generation of maps, and lots of notes for how different games which have already been written chose to address these problems.
Check out Gamasutra. They have loads of articles for all kinds of game development.
The map would be an array of values. It could be divided into discrete parts. Only parts in range of the player would be loaded and the objects & npc in these parts active.
Since the old hardware had very limited memory and cpu, those games would only be able to load and process parts of the maps.

Resources