Layer created is empty even after assigning content to it - coffeescript

I just trying to do a quick prototype following this tutorial:
https://www.youtube.com/watch?v=3zaxrXK7Nac
I'm using my own design for this, the problem is as follows:
When I create a new layer time 8:13 of the posted video and I try to set one of my imported layers as the content of this new layer by using the property image, I get no results.
If I bring this new layer to the screen I can only see black background with transparency, according to the tutorial, it should has the layer I'm assign to it via the image property.
Here is an example of my code:
sketch = Framer.Importer.load("imported/Untitled#2x")
explore_layer = new Layer
width: 750
height: 1334
image: sketch.explore.explore_group
x: screen.width
sketch.Tab_3.on Events.Click, ->
explore_layer.animate
properties:
x: 0
y: 0
curve: "spring(400, 35, 0)"
Here is also a screenshot of my layers
https://gyazo.com/f3fccf7f38813744ea17d259463fabdc

Framer will always import the groups in the selected page of Sketch, and all the groups on that page will transformed into layers that are available on the sketch object directly.
Also: you're now setting the image of a layer to a layer object itself, instead of the image of the sketch layer.
So to get it to work, you need to do a couple of things:
Place all the elements that you want to use on the same page in Sketch
After importing, access those elements directly from the sketch object (so sketch.explore_group instead of sketch.explore.explore_group)
Use the image of the sketch layer, or use the sketch layer itself in your prototype.
Here's an example how it that would look:
sketch = Framer.Importer.load("imported/Untitled#2x")
explore_layer = new Layer
width: 750
height: 1334
image: sketch.explore_group.image
x: screen.width
sketch.Tab_3.on Events.Click, ->
explore_layer.animate
properties:
x: 0
y: 0
curve: "spring(400, 35, 0)"
Or even shorter, and with an updated animation syntax:
sketch = Framer.Importer.load("imported/Untitled#2x")
sketch.explore_group.x = screen.width
sketch.Tab_3.on Events.Click, ->
sketch.explore_group.animate
x: 0
y: 0
options:
curve: Spring(tension:400, friction:35)

Related

SceneKit & Swift: How to use SCN object as floor?

I have created a mountain landscape in Blender and imported it into my Xcode project.
https://github.com/QBeukelman/Mars_Curiosity.git
I would like to drive the SCNVehicle on the landscape as if it were the floor of the scene (landscapeMountains.scn).
The vehicle falls through the landscape!
I have tried the following to solve the issue, but without success:
Different combinations of static, kinetic and dynamic physics bodies.
Using different collision margins such as 0.01
Using category and collision masks (see image)
Does anyone know how to use a scn object as a floor using SceneKit and Xcode?
category & collision bit masks
Replace your entire "// add mountain" code block (line 185 to 191 in GameViewController.swift) with this:
func floorPhysBody(type: SCNPhysicsBodyType = .static, shape: SCNGeometry, scale: SCNVector3 = SCNVector3(1.0,1.0,1.0)) -> SCNPhysicsBody {
// Create Physics Body and set Physics Properties
let body = SCNPhysicsBody(type: type, shape: SCNPhysicsShape(geometry: shape, options: [SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.concavePolyhedron, SCNPhysicsShape.Option.scale: scale]))
// Physics Config
body.isAffectedByGravity = false
return body
}
// configure Physics Floor
let mountain = scene!.rootNode.childNode(withName: "mountain", recursively: true)!
mountain.physicsBody = floorPhysBody(type: .static, shape: mountain.geometry!)
In addition: Your Mountain Geometry is very large (file is over 50MB in size for some geometry). I recommend you to reduce this, to avoid memory issues when your game grows. Also: try to avoid texture sizes bigger than 1024x1024. Use textures sizes from a power of 2 if possible - like 128px, 256px, 512px, 1024px squared.
Have fun with your project.

How to create a 1D Metal Texture?

I want an array of 1-dimensional data (essentially an array of arrays) that is created at run time, so the size of this array is not known at compile time. I want to easily send the array of that data to a kernel shader using setTextures so my kernel can just accept a single argument like texture1d_array which will bind each element texture to a different kernel index automatically, regardless of how many there are.
The question is how to actually create a 1D MTLTexture ? All the MTLTextureDescriptor options seem to focus on 2D or 3D. Is it as simple as creating a 2D texture with the height of 1? Would that then be a 1D texture that the kernel would accept?
I.e.
let textureDescriptor = MTLTextureDescriptor
.texture2DDescriptor(pixelFormat: .r16Uint,
width: length,
height: 1,
mipmapped: false)
If my data is actually just one dimensional (not actually pixel data), is there is an equally convenient way to use an ordinary buffer instead of MTLTexture, with the same flexibility of sending an arbitrarily-sized array of these buffers to the kernel as a single kernel argument?
You can recreate all of those factory methods yourself. I would just use an initializer though unless you run into collisions.
public extension MTLTextureDescriptor {
/// A 1D texture descriptor.
convenience init(
pixelFormat: MTLPixelFormat = .r16Uint,
width: Int
) {
self.init()
textureType = .type1D
self.pixelFormat = pixelFormat
self.width = width
}
}
MTLTextureDescriptor(width: 512)
This is no different than texture2DDescriptor with a height of 1, but it's not as much of a lie. (I.e. yes, a texture can be thought of as infinite-dimensional, with a magnitude of 1 in everything but the few that matter. But we throw out all the dimensions with 1s when saying "how dimensional" something is.)
var descriptor = MTLTextureDescriptor.texture2DDescriptor(
pixelFormat: .r16Uint,
width: 512,
height: 1,
mipmapped: false
)
descriptor.textureType = .type1D
descriptor == MTLTextureDescriptor(width: 512) // true
——
textureType = .typeTextureBuffer takes care of your second question, but why not use textureBufferDescriptor then?

Copying data between metal textures of different shapes

I am converting two trained Keras models to Metal Performance Shaders. I have to reshape the output of the first graph and use it as input to the second graph. The first graph's output is an MPSImage with "shape" (1,1,8192), and the second graph's input is an MPSImage of "shape" (4,4,512).
I cast graph1's output image.texture as a float16 array, and pass it to the following function to copy the data into "midImage", a 4x4x512 MPSImage:
func reshapeTexture(imageArray:[Float16]) -> MPSImage{
let image = imageArray
image.withUnsafeBufferPointer { ptr in
let width = midImage.texture.width
let height = midImage.texture.height
for slice in 0..<128{
for w in 0..<width{
for h in 0..<height{
let region = MTLRegion(origin: MTLOriginMake(w, h, 0),
size: MTLSizeMake(1, 1, 1))
midImage.texture.replace(region: region, mipmapLevel: 0, slice: slice, withBytes: ptr.baseAddress!.advanced(by: ((slice * 4 * width * height) + ((w + h) * 4)), bytesPerRow: MemoryLayout<Float16>.stride * 4, bytesPerImage: 0)
}
}
}
}
return midImage
}
When I pass midImage to graph2, the output of the graph is a square with 3/4 garbled noise, 1/4 black in the bottom right corner. I think I am not understanding something about the MPSImage slice property for storing extra channels. Thanks!
Metal 2d texture arrays are nearly always stored in a Morton or “Z” ordering of some kind. Certainly MPS always allocates them that way, though I suppose on MacOS there may be a means to make a linear 2D texture array and wrap a MPSImage around it. So, without undue care, direct access of a 2d texture array backing store is going to result in sadness and confusion.
The right way to do this is to write a simple Metal copy kernel. This gives you storage order independence and you don’t have to wait for the command buffer to complete before you can do the operation.
A feature request in Radar might also be warranted. Please also look in the latest macOS / iOS seed to see if Apple recently added a reshape filter for you.

SceneKit dynamic object falls through static floor

I have a SceneKit game in swift and in it I have a car with a dynamic physics body that is set up like this:
let carScene = SCNScene(named: "art.scnassets/truck.scn")!
let carNode = carScene.rootNode.childNode(withName: "Cube", recursively: true)!
let carPhysicsBody = SCNPhysicsBody(type: .dynamic,shape: SCNPhysicsShape(geometry: SCNBox(width: 5.343, height: 12.125, length: 4.373, chamferRadius: 0)))
carPhysicsBody.mass = 3
carPhysicsBody.friction = 2
carPhysicsBody.contactTestBitMask = 1
carNode.physicsBody = carPhysicsBody
carNode.position = SCNVector3(x: 0, y: 0, z: 5)
carNode.physicsBody?.applyForce(SCNVector3(x: 0, y: 50, z: 0), asImpulse: true)
car = carNode
floorScene.rootNode.addChildNode(car)
The floor's physics looks like this:
As you can see the car gets launched into the air. Then the gravity in the scene makes it fall, and instead of colliding with the floor, it goes right through it.
The gravity looks like this:
What should I change so it will collide with the floor?
I've made a sample macOS playground, available at github.com/heckj/scenekit-physics-playground that shows a physics body interacting. I suspect the core of the problem in your local example is that the floor object doesn't actually have an SCNPhysicsBody associated with it. Until I explicitly set it on SCNFloor (as static), the text blob "fell through" as you originally described.
I recommend adding sceneView.debugOptions = [.showPhysicsShapes] to see the relevant debugging shapes. I've made (and pushed) a few updates to the above repo. Using stock SCNFloor to establish geometry for the physics collection made a tiny target (which is why the slight horizontal impulse made it appear to "pass through"). This last update sets the floor geometry to a long, wide, thin box.
You want to set the floor to be of the type kinematic, not static. With the car being dynamic and the floor being static, the floor isn't interacting with other objects in any fashion, and you explicitly want a collision.
UPDATE: static vs. kinematic doesn't make a difference for the collision interaction, either work effectively the same way, but having a physics body, and verifying it's size or viewing the interaction with .showPhysicsShapes may answer the underlying question of why they're not interacting.
One of posible solutions for u is to set collisionMargin property for your car from 0.0 to probably 0.01, I had the same problem for ball and plane.

quickest way to get started with cairo

I have taken passing shots at learning Cairo in the past, but always moved on in favor of some other graphics library. My problem is that I can't find a good tutorial that gives me a simple display for my surface. I have always ended up digging through GTK or QT documentation about things that have nothing to do with what I want to do. I want to learn Cairo, not a massive OO architecture.
What is a bare bones wrapper to give me a cross-platform window with a Cairo canvas to draw on?
I have used cairo for virtually anything involving drawing. I work at a medical software company, so I prototype scientific data visualization and other things.
I have usually three ways to display my drawings:
A GTK drawing area created with a Python script and GTK;
A PNG image displayed directly on screen using Python Image Library show() method;
A PNG image saved to disk, also via Python Image Library.
A simple script derived from cairographics examples, which actually I use as a template for any new project, is:
import gtk
class Canvas(gtk.DrawingArea):
def __init__(self):
super(Canvas, self).__init__()
self.connect("expose_event", self.expose)
self.set_size_request(800,500)
def expose(self, widget, event):
cr = widget.window.cairo_create()
rect = self.get_allocation()
# you can use w and h to calculate relative positions which
# also change dynamically if window gets resized
w = rect.width
h = rect.height
# here is the part where you actually draw
cr.move_to(0,0)
cr.line_to(w/2, h/2)
cr.stroke()
window = gtk.Window()
canvas = Canvas()
window.add(canvas)
window.set_position(gtk.WIN_POS_CENTER)
window.show_all()
gtk.main()
Or if you prefer not to deal with GUI toolkits, you can create and display an image on screen, and optionally save it to file:
import cairo, Image
width = 800
height = 600
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
cr = cairo.Context(surface)
# optional conversion from screen to cartesian coordinates:
cr.translate(0, height)
cr.scale(1, -1)
# something very similar to Japanese flag:
cr.set_source_rgb(1,1,1)
cr.rectangle(0, 0, width, height)
cr.fill()
cr.arc(width/2, height/2, 150, 0, 6.28)
cr.set_source_rgb(1,0,0)
cr.fill()
im = Image.frombuffer("RGBA",
(width, height),
surface.get_data(),
"raw",
"BGRA",
0,1) # don't ask me what these are!
im.show()
# im.save('filename', 'png')
An answer to a related question demonstrates a very simple setup in Gtk2HS to draw on a drawingArea with Cairo.
import Graphics.UI.Gtk
import Graphics.Rendering.Cairo
main :: IO ()
main = do
initGUI
window <- windowNew
drawingArea <- drawingAreaNew
containerAdd window drawingArea
drawingArea `onExpose` (\_ -> renderScene drawingArea)
window `onDestroy` mainQuit
windowSetDefaultSize window 640 480
widgetShowAll window
mainGUI
renderScene :: DrawingArea -> IO Bool
renderScene da = do
dw <- widgetGetDrawWindow da
renderWithDrawable dw $ do setSourceRGBA 0.5 0.5 0.5 1.0
moveTo 100.0 100.0
showText "HelloWorld"
return True
Simply pass your Cairo animation routine to renderWithDrawable dw in renderScene.