I created sample application to draw on 3d objects, the output drawing is not smooth(as in figure). I spent nearly a day to figure out what is the issue still not able to solve. What might be the issue?
I am creating custom drawing geometry like below
//I am creating self.drawingNode touches begin and adding to the rootnode
//points are nothing but 2d points from touches
func createGeometryForPoints(points:[CGPoint]) -> SCNGeometry {
var all_3d_points:[SCNVector3] = []
for point in points {
let result = self.get3dPoint(point)
if result.1 == true {
all_3d_points.append(result.0)
} else {
print("INVALID POINT")
}
}
var indices: [Int32] = []
var index:Int32 = 0
var previousIndex:Int32 = -1
for _ in all_3d_points {
if(previousIndex != -1) {
indices.append(previousIndex)
}
indices.append(index)
index = index + 1
previousIndex = index
}
if indices.count > 0 {
indices.removeLast();
}
let indexData = NSData(bytes: indices, length: sizeof(Int32) * indices.count)
let source = SCNGeometrySource.init(vertices: all_3d_points, count: all_3d_points.count)
let element = SCNGeometryElement.init(data: indexData, primitiveType: .Line, primitiveCount: indices.count/2, bytesPerIndex: sizeof(Int32))
let line = SCNGeometry(sources: [source], elements: [element])
line.materials.first?.diffuse.contents = UIColor.redColor()
line.materials.first?.doubleSided = true
return line
}
func get3dPoint(point:CGPoint) -> (SCNVector3,Bool) {
var canAdd = false
let scnView = self.view as! SCNView
var unprojectedStartPoint = SCNVector3.init(x:Float(point.x), y:Float(point.y), z:0)
let hitResults = scnView.hitTest(point, options: nil)
if hitResults.count > 0 {
let result: AnyObject! = hitResults[0]
if hitResults.count > 1 {
print("SOME PROBLEM")
}
unprojectedStartPoint = result.localCoordinates
unprojectedStartPoint = result.node.convertPosition(unprojectedStartPoint, toNode: self.drawingNode!)
canAdd = true
}
return (unprojectedStartPoint,canAdd)
}
EDIT
I am thinking of finding the offset along with the camera direction or normal, since I am new to scenekit i am not getting how to add this offset to drawing node, looking of help here in this direction
func createMarkup() -> Void { let drawingNode = SCNNode() drawingNode.renderingOrder = 1000 self.parentNode!.addChildNode(drawingNode) let geometry = self.createGeometryForPoints(allPoints,node: drawingNode) drawingNode.geometry = geometry drawingNode.geometry?.materials.first?.doubleSided = true }
EDIT: 2
Solved the issue by adding minor offset along the normal of the hit-test
let offsetToAvoidFlickering: Float = 0.05
unprojectedStartPoint = unprojectedStartPoint + result.localNormal.normalized() * offsetToAvoidFlickering
I suspect you have depth precision issues; it looks like parts of your line are being clipped because they are intersecting parts of the sphere. Try drawing the line with depth testing disabled.
the SceneKit State of the Union Demo sample code shows a similar effect, where you can paint on a torus. It's more powerful because you can draw anything (not just line, but splashes from texture etc.) and much more efficient because it doesn't rely on creating new geometry.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With