THIS IS WORK IN PROGRESS.
Arduino & C#
using System.Collections; using System.Collections.Generic; using UnityEngine; public class hand_position_controller : MonoBehaviour { public Transform lh_base; public Transform rh_base; public GameObject lh_go; public GameObject rh_go; public Transform orb_base; public static float hands_distance = 1f; public static int lha = 180; public static int rha = 180; bool lh_present = false; bool rh_present = false; // Update is called once per frame void Update() { Debug.DrawLine( lh_base.transform.position, orb_base.transform.position, Color.yellow,.01f ); Debug.DrawLine( rh_base.transform.position, orb_base.transform.position, Color.yellow,.01f ); Debug.DrawLine( rh_base.transform.position, lh_base.transform.position, Color.red,.01f ); Debug.DrawLine( rh_base.transform.position, rh_base.transform.position+rh_base.transform.up*.1f, Color.blue,.01f ); Debug.DrawLine( lh_base.transform.position, lh_base.transform.position+lh_base.transform.up*.1f, Color.blue,.01f ); Vector3 lhdir = lh_base.transform.position - orb_base.transform.position; Vector3 rhdir = rh_base.transform.position - orb_base.transform.position; // lhdir = lhdir.normalized; Vector3 forward = -transform.forward; float lh_angle = Vector3.SignedAngle(lhdir,forward,Vector3.up); lha = (int)( 360f-(lh_angle+180f) ); float rh_angle = Vector3.SignedAngle(rhdir,forward,Vector3.up); rha = (int)( 360f-(rh_angle+180f) ); if(lh_go.activeSelf){lh_present=true;}else{lh_present=false;} if(rh_go.activeSelf){rh_present=true;}else{rh_present=false;} if(lh_present && rh_present){ hands_distance = Vector3.Distance(rh_base.transform.position, lh_base.transform.position)*2f; hands_distance = Mathf.Clamp(hands_distance,0,1f); }else{ hands_distance = 1f; } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class sender_script : MonoBehaviour { // Class object reference public PTP port; // Start is called before the first frame update void Start() { SendData(); } public void SendData() { // // Transfer data // PTP.DATA d = new PTP.DATA(); int lha = hand_position_controller.lha;// 180;// (int)Random.Range(0,270); int rha = hand_position_controller.rha;//180;// (int)Random.Range(0,270); float sum = (1f-hand_position_controller.hands_distance)*255f;// (int)(Mathf.PerlinNoise(Time.time*2.1f,12f)*255f); //sum *= 0f;// (Mathf.Sin(Time.time*1f)+1); // Basic primitive types // d.PushToPackBool(true); d.PushToPackInt( lha ); d.PushToPackInt( rha ); d.PushToPackInt( (int)sum ); // Handshake String // d.PushToPackString("fikki"); // // Transfer // port.TransceiveData(d); Invoke("SendData",.4f); } }
#include "TP4/STP4.h" #include <Adafruit_NeoPixel.h> #include <avr/power.h> #define PIN 6 #define NUMPIXELS 32 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); // Port speed #define baudRate 115200 // Open serial port STP4* port; // char* str_test = "fikki"; float ta_one = 360; float ta_two = 0; float stepper = 11.25; float angle_one = 0; float angle_two = 0; float main_sum = 0; float main_sum_t = 0; float cursor_wideness = 3.2; void setup() { port = new STP4(baudRate); pinMode(13, OUTPUT); digitalWrite(13, LOW); pixels.begin(); initLEDS(); } void loop() { // 1. Wait Data if (port->Listen()) { bool val_bool = port->GetVal<bool>(); int lha = port->GetVal<int>(); int rha = port->GetVal<int>(); int sum = port->GetVal<int>(); ta_one = lha; ta_two = rha; main_sum_t = sum; // HANDSHAKE String // char* str_chr = port->GetArr<char>(); // 4. Clear RAM // delete[] arr_int; delete[] str_chr; } int smooth_amount = 7; angle_one = angle_one + ((ta_one -angle_one)/smooth_amount); angle_two = angle_two + ((ta_two -angle_two)/smooth_amount); main_sum = main_sum + ((main_sum_t -main_sum)/(smooth_amount*.5)); operateSTRIPE(); }
older protos
using System.Collections; using System.Collections.Generic; using UnityEngine; public class hand_position_controller : MonoBehaviour { public Transform lh_base; public Transform rh_base; public Transform orb_base; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { Debug.DrawLine( lh_base.transform.position, orb_base.transform.position, Color.yellow,.01f ); Debug.DrawLine( rh_base.transform.position, orb_base.transform.position, Color.yellow,.01f ); Debug.DrawLine( rh_base.transform.position, lh_base.transform.position, Color.red,.01f ); Debug.DrawLine( rh_base.transform.position, rh_base.transform.position+rh_base.transform.up*.1f, Color.blue,.01f ); Debug.DrawLine( lh_base.transform.position, lh_base.transform.position+lh_base.transform.up*.1f, Color.blue,.01f ); } } void operateSTRIPE(){ float mainpulse = main_sum*.3;// 0;// (sin(millis()*.001)+1)*12; for(int i=0;i<NUMPIXELS;i++){ float disti = abs(angle_one/stepper-float(i)); float disti2 = abs( angle_two/stepper - float(i) ); int bri = 0; int bri2 = 0; if(disti<cursor_wideness){ bri = (cursor_wideness-disti )*90; } if(disti2<cursor_wideness){ bri2=(cursor_wideness-disti2 )*90; } bri = constrain(bri,0,200); bri2 = constrain(bri2,0,200); int brisum = (bri+bri2); brisum = constrain(brisum,0,255); brisum *= main_sum/float(255) ; pixels.setPixelColor(i, pixels.Color(brisum ,brisum,brisum )); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. } } // ---------------------------------- void initLEDS(){ for(int i=0;i<NUMPIXELS;i++){ pixels.setPixelColor(i, pixels.Color(0,0,0)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. } delay(64); }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class aFINGERTIP { public int id; public Transform trans; public bool is_inside = false; public bool is_touching = false; public Vector3 ppos = Vector3.zero; public Vector3 svel = Vector3.zero; public aFINGERTIP(int _id, Transform _tr){ this.id = _id; this.trans = _tr; } public void updateFT(){ Vector3 diff = ppos - trans.position; svel = Vector3.Slerp(svel,diff,.03f); Debug.DrawLine( trans.position, trans.position+ svel*22f,Color.blue,.01f ); //smooth_velocity ppos = trans.position; } } public class fingertip_touch_tracker : MonoBehaviour { // todo > make surface touch event! // track fingertip velocity aFINGERTIP[] allFINGERTIPS; public Transform[] fingertips; public GameObject target_go; Collider target_collider; RaycastHit hit; public int touching_fingertips_sum = 0; public int digging_fingertips_sum = 0; // Start is called before the first frame update void Start() { target_collider = target_go.GetComponent<Collider>(); init(); } void init(){ allFINGERTIPS = new aFINGERTIP[fingertips.Length]; for(int i=0;i<fingertips.Length;i++){ allFINGERTIPS [ i ] = new aFINGERTIP(i,fingertips[i]); } } // Update is called once per frame void Update() { touching_fingertips_sum = 0; digging_fingertips_sum = 0; for(int i=0;i<allFINGERTIPS.Length;i++){ aFINGERTIP cft = allFINGERTIPS[i]; cft.updateFT(); Vector3 dir = target_go.transform.position - cft.trans.position; if (Physics.Raycast(cft.trans.position, transform.TransformDirection(dir), out hit, .25f)) { float cdist = Vector3.Distance(hit.point,cft.trans.position); Debug.DrawRay(hit.point, hit.transform.TransformDirection(hit.normal) * cdist, Color.red); if(cdist<.02f){ cft.is_touching = true; touching_fingertips_sum++; } if(cdist>.04f){ cft.is_touching = false; } cft.is_inside = false; }else{ bool isin = IsInside(target_collider, cft.trans.position); if(isin){ // Debug.Log("is in:" + i); // touching_fingertips_sum++; cft.is_inside = true; digging_fingertips_sum++; }else{ cft.is_inside = false; } } } } public static bool IsInside(Collider c, Vector3 point) { Vector3 closest = c.ClosestPoint(point); // Because closest=point if point is inside - not clear from docs I feel return closest == point; } void OnDrawGizmos() { // Debug.Log("yoo"+ allFINGERTIPS.Length); for(int i=0;i<allFINGERTIPS.Length;i++){ aFINGERTIP cft = allFINGERTIPS[i]; //Debug.Log(cft.trans.position); if(cft.is_inside){ float s = cft.svel.magnitude*10f; // Draw a yellow sphere at the transform's position Gizmos.color = Color.yellow; Gizmos.DrawSphere(cft.trans.position, s); } } } }