Commit 87dcc74a authored by SimonP's avatar SimonP
Browse files

Initial Unity Project Commit

parent 4093aedc
fileFormatVersion: 2
guid: ed8ab5107299d0b4f9fcfabb717aee5c
timeCreated: 1499813316
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: eac06716687d88841972672bb447b67b
folderAsset: yes
timeCreated: 1499788572
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 15c597d410cac21419811fcc3f3ced76
timeCreated: 1499791460
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 4aac37b408d208149943e1d3677a47ae
folderAsset: yes
timeCreated: 1499788566
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class InverseKinematics : MonoBehaviour {
public Transform upperArm;
public Transform forearm;
public Transform hand;
public Transform elbow;
public Transform target;
[Space(20)]
public Vector3 uppperArm_OffsetRotation;
public Vector3 forearm_OffsetRotation;
public Vector3 hand_OffsetRotation;
[Space(20)]
public bool handMatchesTargetRotation = true;
[Space(20)]
public bool debug;
float angle;
float upperArm_Length;
float forearm_Length;
float arm_Length;
float targetDistance;
float adyacent;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void LateUpdate () {
if(upperArm != null && forearm != null && hand != null && elbow != null && target != null){
upperArm.LookAt (target, elbow.position - upperArm.position);
upperArm.Rotate (uppperArm_OffsetRotation);
Vector3 cross = Vector3.Cross (elbow.position - upperArm.position, forearm.position - upperArm.position);
upperArm_Length = Vector3.Distance (upperArm.position, forearm.position);
forearm_Length = Vector3.Distance (forearm.position, hand.position);
arm_Length = upperArm_Length + forearm_Length;
targetDistance = Vector3.Distance (upperArm.position, target.position);
targetDistance = Mathf.Min (targetDistance, arm_Length - arm_Length * 0.001f);
adyacent = ((upperArm_Length * upperArm_Length) - (forearm_Length * forearm_Length) + (targetDistance * targetDistance)) / (2*targetDistance);
angle = Mathf.Acos (adyacent / upperArm_Length) * Mathf.Rad2Deg;
upperArm.RotateAround (upperArm.position, cross, -angle);
forearm.LookAt(target, cross);
forearm.Rotate (forearm_OffsetRotation);
if(handMatchesTargetRotation){
hand.rotation = target.rotation;
hand.Rotate (hand_OffsetRotation);
}
if(debug){
if (forearm != null && elbow != null) {
Debug.DrawLine (forearm.position, elbow.position, Color.blue);
}
if (upperArm != null && target != null) {
Debug.DrawLine (upperArm.position, target.position, Color.red);
}
}
}
}
void OnDrawGizmos(){
if (debug) {
if(upperArm != null && elbow != null && hand != null && target != null && elbow != null){
Gizmos.color = Color.gray;
Gizmos.DrawLine (upperArm.position, forearm.position);
Gizmos.DrawLine (forearm.position, hand.position);
Gizmos.color = Color.red;
Gizmos.DrawLine (upperArm.position, target.position);
Gizmos.color = Color.blue;
Gizmos.DrawLine (forearm.position, elbow.position);
}
}
}
}
fileFormatVersion: 2
guid: 30d20bcf9ec4ed24b97a6e8ab136c34f
timeCreated: 1499795966
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: d2b4d2bce3a568e41a5e6998a2b71cef
folderAsset: yes
timeCreated: 1499788558
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: f3b8a1b2025a2b14da282ba7b5b7e9a1
timeCreated: 1499789160
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 1
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: 4
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
- buildTarget: Android
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Windows Store Apps
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 291ee55cb45c2d34ebebbe622a511da0
timeCreated: 1499788732
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: 4
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 1
- buildTarget: Android
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Windows Store Apps
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: WebGL
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 37090212bba33504ca8766e654c9b773
folderAsset: yes
timeCreated: 1491488955
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
namespace ProceduralToolkit
{
/// <summary>
/// Array extensions
/// </summary>
public static class ArrayE
{
/// <summary>
/// Gets the next or the first node in the <see cref="LinkedList{T}"/>
/// </summary>
public static LinkedListNode<T> NextOrFirst<T>(this LinkedListNode<T> current)
{
return current.Next ?? current.List.First;
}
/// <summary>
/// Gets the previous or the last node in the <see cref="LinkedList{T}"/>
/// </summary>
public static LinkedListNode<T> PreviousOrLast<T>(this LinkedListNode<T> current)
{
return current.Previous ?? current.List.Last;
}
/// <summary>
/// Looped indexer getter, allows out of bounds indices
/// </summary>
public static T GetLooped<T>(this T[] array, int index)
{
if (index < 0)
{
index = index%array.Length + array.Length;
}
else if (index >= array.Length)
{
index %= array.Length;
}
return array[index];
}
/// <summary>
/// Looped indexer setter, allows out of bounds indices
/// </summary>
public static void SetLooped<T>(this T[] array, int index, T value)
{
if (index < 0)
{
index = index%array.Length + array.Length;
}
else if (index >= array.Length)
{
index %= array.Length;
}
array[index] = value;
}
/// <summary>
/// Looped indexer getter, allows out of bounds indices
/// </summary>
public static T GetLooped<T>(this List<T> array, int index)
{
if (index < 0)
{
index = index%array.Count + array.Count;
}
else if (index >= array.Count)
{
index %= array.Count;
}
return array[index];
}
/// <summary>
/// Looped indexer setter, allows out of bounds indices
/// </summary>
public static void SetLooped<T>(this List<T> array, int index, T value)
{
if (index < 0)
{
index = index%array.Count + array.Count;
}
else if (index >= array.Count)
{
index %= array.Count;
}
array[index] = value;
}
/// <summary>
/// Checks if <paramref name="vector"/> is within array bounds
/// </summary>
public static bool IsInBounds<T>(this T[,] array, Vector2Int vector)
{
return IsInBounds(array, vector.x, vector.y);
}
/// <summary>
/// Checks if <paramref name="x"/> and <paramref name="y"/> are within array bounds
/// </summary>
public static bool IsInBounds<T>(this T[,] array, int x, int y)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
return x >= 0 && x < array.GetLength(0) && y >= 0 && y < array.GetLength(1);
}
/// <summary>
/// Visits all connected elements with the same value as start element
/// </summary>
/// <remarks>
/// https://en.wikipedia.org/wiki/Flood_fill
/// </remarks>
public static void FloodVisit<T>(this T[,] array, Vector2Int start, Action<int, int> visit)
{
FloodVisit(array, start.x, start.y, visit);
}
/// <summary>
/// Visits all connected elements with the same value as start element
/// </summary>
/// <remarks>
/// https://en.wikipedia.org/wiki/Flood_fill
/// </remarks>
public static void FloodVisit<T>(this T[,] array, int startX, int startY, Action<int, int> visit)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if (visit == null)
{
throw new ArgumentNullException("visit");
}
if (startX < 0 || startX >= array.GetLength(0))
{
throw new ArgumentOutOfRangeException("startX");
}
if (startY < 0 || startY >= array.GetLength(1))
{
throw new ArgumentOutOfRangeException("startY");
}
bool[,] processed = new bool[array.GetLength(0), array.GetLength(1)];
T value = array[startX, startY];
var queue = new Queue<Vector2Int>();
queue.Enqueue(new Vector2Int(startX, startY));
processed[startX, startY] = true;
while (queue.Count > 0)
{
Vector2Int cell = queue.Dequeue();
array.VisitVonNeumannNeighbours(cell.x, cell.y, true, (x, y) =>
{
if (array[x, y].Equals(value) && !processed[x, y])
{
queue.Enqueue(new Vector2Int(x, y));
processed[x, y] = true;
}
});
visit(cell.x, cell.y);
}
}
/// <summary>
/// Visits all connected elements with the same value as start element
/// </summary>
/// <remarks>
/// https://en.wikipedia.org/wiki/Flood_fill
/// </remarks>
public static void FloodVisit<T>(this T[,] array, Vector2Int start, Action<int, int, bool> visit)
{
FloodVisit(array, start.x, start.y, visit);
}
/// <summary>
/// Visits all connected elements with the same value as start element
/// </summary>
/// <remarks>
/// https://en.wikipedia.org/wiki/Flood_fill
/// </remarks>
public static void FloodVisit<T>(this T[,] array, int startX, int startY, Action<int, int, bool> visit)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if (visit == null)
{
throw new ArgumentNullException("visit");
}
if (startX < 0 || startX >= array.GetLength(0))
{
throw new ArgumentOutOfRangeException("startX");
}
if (startY < 0 || startY >= array.GetLength(1))
{
throw new ArgumentOutOfRangeException("startY");
}
bool[,] processed = new bool[array.GetLength(0), array.GetLength(1)];
T value = array[startX, startY];
var queue = new Queue<Vector2Int>();
queue.Enqueue(new Vector2Int(startX, startY));
processed[startX, startY] = true;
while (queue.Count > 0)
{
Vector2Int cell = queue.Dequeue();
bool isBorderCell = false;
array.VisitMooreNeighbours(cell.x, cell.y, false, (x, y) =>
{
if (array.IsInBounds(x, y))
{
if (array[x, y].Equals(value))
{
bool vonNeumannNeighbour = (x == cell.x || y == cell.y);
if (vonNeumannNeighbour && !processed[x, y])
{
queue.Enqueue(new Vector2Int(x, y));
processed[x, y] = true;