void TapAction(UITapGestureRecognizer tap) { if (tap.State == UIGestureRecognizerState.Ended) { var tapLocation = tap.LocationInView(sceneView); var hitResults = sceneView.HitTest(tapLocation, new NSDictionary()); if (hitResults.Length != 0) { var NodeResult = hitResults[0].Node; if (NodeResult != null) { var nodeText = SCNText.Create(NodeResult.Name, 5); var textNode = SCNNode.Create(); textNode.Geometry = nodeText; textNode.Scale = new SCNVector3(0.01f, 0.01f, 0.01f); var min = new SCNVector3(); var max = new SCNVector3(); textNode.GetBoundingBox(ref min, ref max); textNode.Position = new SCNVector3((textNode.Position.X - (textNode.Scale.X / 2)), textNode.Position.Y + 0.5f, textNode.Position.Z); NodeResult.AddChildNode(textNode); } } } }
SCNGeometry CreateGeometry(string text, float extrusionDepth, UIColor color) { SCNText geometry = SCNText.Create(text, extrusionDepth); geometry.Font = UIFont.FromName("Arial", 0.15f); geometry.Flatness = 0; geometry.FirstMaterial.DoubleSided = true; geometry.FirstMaterial.Diffuse.Contents = color; return(geometry); }
public override void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor) { if (anchor is ARImageAnchor imageAnchor) { var box = new SCNBox(); nfloat width = imageAnchor.ReferenceImage.PhysicalSize.Width; nfloat height = imageAnchor.ReferenceImage.PhysicalSize.Height; box.Width = width; box.Height = height; box.Length = (System.nfloat) 0.1; box.FirstMaterial.Diffuse.Contents = UIColor.Orange; SCNText text = SCNText.Create("Enter Here", (System.nfloat) 0.1); text.Font = UIFont.SystemFontOfSize(1); text.Flatness = (System.nfloat) 0.05; text.FirstMaterial.Diffuse.Contents = UIColor.Red; var textNode = new SCNNode { Geometry = text, }; textNode.Scale = new SCNVector3((float)0.5, (float)0.5, (float)0.5); textNode.EulerAngles = new SCNVector3((float)(-1.57), 0, 0); textNode.Position = new SCNVector3 { X = (float)(imageAnchor.Transform.Column3.X + 2), Y = imageAnchor.Transform.Column3.Y - 2, Z = imageAnchor.Transform.Column3.Z }; var boxNode = new SCNNode { Geometry = box, Position = new SCNVector3 { X = -imageAnchor.Transform.Column3.X / 2, Y = -imageAnchor.Transform.Column3.Y, Z = imageAnchor.Transform.Column3.Z } }; node.AddChildNode(textNode); //node.AddChildNode(boxNode); } }
/// <summary> /// Geometry to create the 3D effect /// </summary> /// <param name="text">string text</param> /// <param name="color">color of text</param> /// <returns>3D text in specified color</returns> private static SCNGeometry CreateGeometry(string text, UIColor color) { var geometry = SCNText.Create(text, 0.01f); geometry.Font = UIFont.FromName("Courier", 0.5f); geometry.Flatness = 0; geometry.FirstMaterial.DoubleSided = true; geometry.FirstMaterial.Diffuse.Contents = color; geometry.FirstMaterial.Specular.Contents = UIColor.Blue; return(geometry); }
public void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor) { var planeAnchor = anchor as ARPlaneAnchor; if (planeAnchor == null) { return; } Console.WriteLine("didAddNode"); var text = SCNText.Create("This is a good spot", 0); text.Font = UIFont.FromName("Arial", 1); if (text.FirstMaterial != null) { text.FirstMaterial.Diffuse.Contents = UIColor.Green; } var textNode = SCNNode.FromGeometry(text); textNode.Position = new SCNVector3(-0.3f, -0.55f, 0.25f); textNode.Scale = new SCNVector3(0.075f, 0.1f, 0.5f); var plane = SCNPlane.Create(new nfloat(planeAnchor.Extent.X), new nfloat(planeAnchor.Extent.Z)); var planeNode = SCNNode.FromGeometry(plane); planeNode.Position = new SCNVector3(planeAnchor.Center.X, 0f, planeAnchor.Center.Z); var txtAngles = textNode.EulerAngles; txtAngles.X = (float)(-1f * (Math.PI / 2f)); textNode.EulerAngles = txtAngles; var planeAngles = planeNode.EulerAngles; planeAngles.X = (float)(-1f * (Math.PI / 2f)); planeNode.EulerAngles = planeAngles; planeNode.Opacity = 0.25f; node.AddChildNode(planeNode); node.AddChildNode(textNode); }
public static SCNNode SCLabelNode(string message, LabelSize size, bool isLit) { var node = SCNNode.Create(); var text = SCNText.Create(message, 0); node.Geometry = text; node.Scale = new SCNVector3((0.01f * (int)size), (0.01f * (int)size), (0.01f * (int)size)); text.Flatness = 0.4f; // Use Myriad it's if available, otherwise Avenir text.Font = NSFont.FromFontName("Myriad Set", 50) != null?NSFont.FromFontName("Myriad Set", 50) : NSFont.FromFontName("Avenir Medium", 50); if (!isLit) { text.FirstMaterial.LightingModelName = SCNLightingModel.Constant; } return(node); }
static SCNNode CreateTextNode(string text, UIFont font, UIColor color, UIColor bgColor, float kerning = 0) { kerning = 1; var attrString = new NSMutableAttributedString(text, font); var textGeometry = SCNText.Create(attrString, 0); textGeometry.FirstMaterial.Diffuse.Contents = UIColor.DarkTextColor; textGeometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; textGeometry.FirstMaterial.DoubleSided = true; textGeometry.FirstMaterial.ReadsFromDepthBuffer = false; textGeometry.FirstMaterial.WritesToDepthBuffer = false; textGeometry.ChamferRadius = 0f; var textNode = new SCNNode { Geometry = textGeometry }; textNode.Center(); var container = CreateBackgroundPlaneNode(textNode.Size(), bgColor, 0); container.AddChildNode(textNode); return(container); }
private void PlaceFeature(string message, CGPoint p, float offset) { // Create and configure a node with a text geometry, and add it to the scene var text = SCNText.Create(message, 5); text.Font = Font; text.Flatness = 0.4f; text.Materials = Materials; var textNode = SCNNode.Create(); textNode.Geometry = text; textNode.Position = new SCNVector3(p.X, p.Y + Altitude, 0); textNode.Scale = new SCNVector3(0.02f, 0.02f, 0.02f); ContentNode.AddChildNode(textNode); // Animation the node's position and opacity var positionAnimation = CABasicAnimation.FromKeyPath("position.z"); positionAnimation.From = NSNumber.FromInt16(-10); positionAnimation.To = NSNumber.FromInt16(14); positionAnimation.Duration = 7.0f; positionAnimation.TimeOffset = -offset * positionAnimation.Duration; positionAnimation.RepeatCount = float.MaxValue; textNode.AddAnimation(positionAnimation, new NSString("positionAnimation")); var opacityAnimation = CAKeyFrameAnimation.FromKeyPath("opacity"); opacityAnimation.KeyTimes = new NSNumber[] { 0.0f, 0.2f, 0.9f, 1.0f }; opacityAnimation.Values = new NSNumber[] { 0.0f, 1.0f, 1.0f, 0.0f }; opacityAnimation.Duration = positionAnimation.Duration; opacityAnimation.TimeOffset = positionAnimation.TimeOffset; opacityAnimation.RepeatCount = float.MaxValue; textNode.AddAnimation(opacityAnimation, new NSString("opacityAnimation")); }
// Takes a string an creates a node hierarchy where each letter is an independent geometry that is animated private SCNNode SplittedStylizedText(string message) { var textNode = SCNNode.Create(); var frontMaterial = TextFrontMaterial(); var border = TextSideAndChamferMaterial(); // Current x position of the next letter to add var positionX = 0.0f; // For each letter for (var i = 0; i < message.Length; i++) { var letterNode = SCNNode.Create(); var letterString = message.Substring(i, 1); var text = SCNText.Create(letterString, 50.0f); text.Font = NSFont.FromFontName("Avenir Next Heavy", 288); text.ChamferRadius = 3.0f; text.ChamferProfile = TextChamferProfile(); // use a different material for the "heart" character var finalFrontMaterial = frontMaterial; if (i == 1) { finalFrontMaterial = (SCNMaterial)finalFrontMaterial.Copy(); finalFrontMaterial.Diffuse.Contents = NSColor.Red; finalFrontMaterial.Reflective.Contents = NSColor.Black; letterNode.Scale = new SCNVector3(1.1f, 1.1f, 1.0f); } text.Materials = new SCNMaterial[] { finalFrontMaterial, finalFrontMaterial, border, border, border }; letterNode.Geometry = text; textNode.AddChildNode(letterNode); // measure the letter we just added to update the position SCNVector3 min, max; max = new SCNVector3(0, 0, 0); min = new SCNVector3(0, 0, 0); if (letterNode.GetBoundingBox(ref min, ref max)) { letterNode.Position = new SCNVector3(positionX - min.X + (max.X + min.X) * 0.5f, -min.Y, 0); positionX += (float)max.X; } else { // if we have no bounding box, it is probably because of the "space" character. In that case, move to the right a little bit. positionX += 50.0f; } // Place the pivot at the center of the letter so that the rotation animation looks good letterNode.Pivot = SCNMatrix4.CreateTranslation((max.X + min.X) * 0.5f, 0, 0); // Animate the letter var animation = CAKeyFrameAnimation.GetFromKeyPath("rotation"); animation.Duration = 4.0f; animation.KeyTimes = new NSNumber[] { 0.0f, 0.3f, 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector(new SCNVector4(0, 1, 0, 0)), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))) }; var timingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimingFunctions = new CAMediaTimingFunction[] { timingFunction, timingFunction, timingFunction }; animation.RepeatCount = float.MaxValue; animation.BeginTime = CAAnimation.CurrentMediaTime() + 1.0 + i * 0.2; // desynchronize animations letterNode.AddAnimation(animation, new NSString("letterNodeAnimation")); } return(textNode); }
private SCNNode NodeWithText(string message, TextType type, int level) { var textNode = SCNNode.Create(); // Bullet if (type == TextType.Bullet) { if (level == 0) { message = "• " + message; } else { var bullet = SCNNode.Create(); bullet.Geometry = SCNPlane.Create(10.0f, 10.0f); bullet.Geometry.FirstMaterial.Diffuse.Contents = NSColor.FromDeviceRgba((float)(160 / 255.0), (float)(182 / 255.0), (float)(203 / 255.0), 1); bullet.Position = new SCNVector3(80, 30, 0); bullet.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; bullet.Geometry.FirstMaterial.WritesToDepthBuffer = false; bullet.RenderingOrder = 1; textNode.AddChildNode(bullet); message = "\t\t\t\t" + message; } } // Text attributes var extrusion = ExtrusionDepthForTextType(type); var text = SCNText.Create(message, extrusion); textNode.Geometry = text; text.Flatness = TEXT_FLATNESS; text.ChamferRadius = (extrusion == 0 ? 0 : TEXT_CHAMFER); text.Font = FontForTextType(type, level); // Layout var layoutManager = new NSLayoutManager(); var leading = layoutManager.DefaultLineHeightForFont(text.Font); var descender = text.Font.Descender; int newlineCount = ((string[])(((string)text.String.ToString()).Split('\n'))).Length; textNode.Pivot = SCNMatrix4.CreateTranslation(0, -descender + newlineCount * leading, 0); if (type == TextType.Chapter) { var min = new SCNVector3(); var max = new SCNVector3(); textNode.GetBoundingBox(ref min, ref max); textNode.Position = new SCNVector3(-11, (-min.Y + textNode.Pivot.M42) * TEXT_SCALE, 7); textNode.Scale = new SCNVector3(TEXT_SCALE, TEXT_SCALE, TEXT_SCALE); textNode.Rotation = new SCNVector4(0, 1, 0, (float)(Math.PI / 270.0)); } else { textNode.Position = new SCNVector3(-16, CurrentBaseline, 0); textNode.Scale = new SCNVector3(TEXT_SCALE, TEXT_SCALE, TEXT_SCALE); } // Material if (type == TextType.Chapter) { var frontMaterial = SCNMaterial.Create(); var sideMaterial = SCNMaterial.Create(); frontMaterial.Emission.Contents = NSColor.DarkGray; frontMaterial.Diffuse.Contents = ColorForTextType(type, level); sideMaterial.Diffuse.Contents = NSColor.LightGray; textNode.Geometry.Materials = new SCNMaterial[] { frontMaterial, frontMaterial, sideMaterial, frontMaterial, frontMaterial }; } else { // Full white emissive material (visible even when there is no light) textNode.Geometry.FirstMaterial = SCNMaterial.Create(); textNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Black; textNode.Geometry.FirstMaterial.Emission.Contents = ColorForTextType(type, level); // Don't write to the depth buffer because we don't want the text to be reflected textNode.Geometry.FirstMaterial.WritesToDepthBuffer = false; // Render last textNode.RenderingOrder = 1; } return(textNode); }