Skip to content

Instantly share code, notes, and snippets.

@Frooxius
Created June 5, 2018 07:04
Show Gist options
  • Save Frooxius/d9fd41ec68c0a62265657353ecc51f8f to your computer and use it in GitHub Desktop.
Save Frooxius/d9fd41ec68c0a62265657353ecc51f8f to your computer and use it in GitHub Desktop.
PenTip Source
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BaseX;
namespace FrooxEngine
{
[Category("Tools/Tooltips")]
public class PenTip : ToolTip
{
public readonly Sync<float> MaxRadius;
readonly Sync<bool> Flat;
readonly SyncRef<PBS_Metallic> Material;
readonly SyncRef<Slot> _flatTip;
TubeMesh painting;
StripeMesh flatPainting;
float3 lastPosition;
bool IsPainting { get { return painting != null || flatPainting != null; } }
public override float3 LocalTip => float3.Forward * 0.075f;
protected override void OnInit()
{
base.OnInit();
MaxRadius.Value = 0.01f;
}
protected override void OnAttach()
{
base.OnAttach();
var visual = Slot.AddSlot("Visual");
visual.AttachComponent<SphereCollider>().Radius.Value = 0.02f;
visual.LocalRotation = floatQ.Euler(90, 0, 0);
visual.LocalPosition += float3.Forward * 0.05f;
Material.Target = visual.AttachComponent<PBS_Metallic>();
var cone = visual.AttachMesh<ConeMesh>(Material.Target);
cone.RadiusBase.Value = 0.015f;
cone.Height.Value = 0.05f;
visual = visual.AddSlot("FlatTip");
visual.LocalPosition += float3.Up * 0.025f;
var box = visual.AttachMesh<BoxMesh>(Material.Target);
box.Size.Value = new float3(0.05f, 0.01f, 0.002f);
_flatTip.Target = visual;
_flatTip.Target.ActiveSelf = false;
}
public override void Update(float primaryStrength, float2 secondaryAxis, Digital primary, Digital secondary)
{
if (primaryStrength > 0.05f)
{
if (!IsPainting)
{
var s = World.AddSlot("Line");
s.GlobalPosition = Slot.GlobalPosition;
lastPosition = Slot.GlobalPosition;
if (Flat)
{
var r = s.AttachMesh<StripeMesh, PBS_Metallic>();
flatPainting = r.mesh;
}
else
{
var r = s.AttachMesh<TubeMesh, PBS_Metallic>();
painting = r.mesh;
}
PaintPoint(0f);
}
else
{
PaintPoint(primaryStrength * MaxRadius);
}
}
else if (IsPainting)
{
PaintPoint(0f);
var slot = painting?.Slot ?? flatPainting.Slot;
// attach mesh collider & grabbable
var meshCollider = slot.AttachComponent<MeshCollider>();
if (painting != null)
meshCollider.Mesh.Target = painting;
else
meshCollider.Mesh.Target = flatPainting;
slot.AttachComponent<Grabbable>().Scalable = true;
painting = null;
flatPainting = null;
}
}
public override void OnSecondaryPress()
{
Flat.Value = !Flat.Value;
_flatTip.Target.ActiveSelf = Flat.Value;
MaxRadius.Value = Flat.Value ? MaxRadius * 4 : MaxRadius / 4;
}
void PaintPoint(float radius)
{
if (painting != null)
{
painting.Points.Append(new TubePoint(
painting.Slot.GlobalPointToLocal(Tip), radius));
}
else
{
var lastLocalPos = flatPainting.Slot.GlobalPointToLocal(lastPosition);
var currentLocalPos = flatPainting.Slot.GlobalPointToLocal(Slot.GlobalPosition);
var localUp = flatPainting.Slot.GlobalDirectionToLocal(Slot.Up);
var localForward = flatPainting.Slot.GlobalDirectionToLocal(Slot.Forward);
var computedForward = (currentLocalPos - lastLocalPos).Normalized;
/*if (MathX.Dot(localForward, computedForward) < 0f)
localForward = -localForward;*/
var rot = floatQ.LookRotation(computedForward, localUp);
if (lastPosition == Slot.GlobalPosition)
rot = floatQ.Identity;
lastPosition = Slot.GlobalPosition;
flatPainting.Points.Append(new StripePoint(
flatPainting.Slot.GlobalPointToLocal(Tip), rot, radius));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment