roomed up

This commit is contained in:
spatialfree 2022-03-17 16:55:59 -04:00
parent f5088a8304
commit a7a0a0f09d
31 changed files with 902 additions and 285 deletions

103
.past/Oriel.cs Normal file
View file

@ -0,0 +1,103 @@
using System;
using System.Runtime.InteropServices;
using StereoKit;
// [StructLayout(LayoutKind.Sequential)]
// struct BufferData {
// public Vec3 position;
// public float time;
// }
public class Oriel {
Monolith mono;
public Bounds bounds;
Material mat = new Material(Shader.FromFile("oriel.hlsl"));
Mesh mesh = Default.MeshCube;
public float crown = 0.0666f;
bool scalingOriel = false;
bool draggingOriel = false;
Vec3 orielOffset = Vec3.Zero;
// MaterialBuffer<BufferData> buffer;
public void Start(Monolith mono, int bufferIndex) {
this.mono = mono;
bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f));
bounds.center = new Vec3(0.5f, -0.25f, -1f);
// buffer = new MaterialBuffer<BufferData>(bufferIndex);
}
// BufferData data = new BufferData();
public void Step() {
Vec3 rGlovePos = mono.rGlove.virtualGlove.position;
Vec3 lGlovePos = mono.lGlove.virtualGlove.position;
if (mono.rCon.triggerBtn.held && mono.lCon.triggerBtn.held) {
if (!scalingOriel) {
if (bounds.Contains(rGlovePos) || bounds.Contains(lGlovePos)) {
scalingOriel = true;
}
} else {
bounds.center = Vec3.Lerp(rGlovePos, lGlovePos, 0.5f);
float distX = Math.Abs(rGlovePos.x - lGlovePos.x);
float distY = Math.Abs(rGlovePos.y - lGlovePos.y);
float distZ = Math.Abs(rGlovePos.z - lGlovePos.z);
bounds.dimensions = new Vec3(distX, distY, distZ);
}
} else {
scalingOriel = false;
}
if (!scalingOriel && mono.rCon.triggerBtn.held) {
if (!draggingOriel) {
bool inCrown = rGlovePos.y > (bounds.center.y + bounds.dimensions.y / 2.0) - crown;
if (bounds.Contains(rGlovePos) && inCrown) {
orielOffset = rGlovePos - bounds.center;
draggingOriel = true;
}
} else {
bounds.center = rGlovePos - orielOffset;
}
} else {
draggingOriel = false;
}
// data.position = rGlovePos;
// data.time = (float)Time.Total;
// buffer.Set(data);
Matrix matrix = Matrix.TR(
bounds.center,
Quat.FromAngles(0, Time.Totalf * 12, 0).Normalized * Quat.FromAngles(90, 0, 0) * Quat.FromAngles(0, 90, 0)
).Inverse;
mat["_matrix"] = (Matrix)System.Numerics.Matrix4x4.Transpose(matrix);
// circle around center
// bounds.center = Quat.FromAngles(0, 0, Time.Totalf * 60) * Vec3.Up * 0.3f;
// bounds.dimensions = _dimensions * (1f + (MathF.Sin(Time.Totalf * 3) * 0.3f));
mat.FaceCull = Cull.Front;
mat.SetFloat("_distmax", 1000);
mat.SetVector("_dimensions", bounds.dimensions);
mat.SetVector("_center", bounds.center);
mat.SetFloat("_crown", crown);
// Pose pose = mono.rGlove.virtualGlove;
// pose.position -= bounds.center;
// mat.SetMatrix("_matrix", pose.ToMatrix());
mat["_rGlove"] = (Matrix)System.Numerics.Matrix4x4.Transpose(mono.rGlove.virtualGlove.ToMatrix().Inverse);
mat["_lGlove"] = (Matrix)System.Numerics.Matrix4x4.Transpose(mono.lGlove.virtualGlove.ToMatrix().Inverse);
Matrix m = Matrix.TRS(bounds.center, Quat.Identity, bounds.dimensions);
Pose head = Input.Head;
mesh.Draw(mat, m);
}
}

268
.past/oriel.hlsl Normal file
View file

@ -0,0 +1,268 @@
#include "stereokit.hlsli"
// --name = dofdev/oriel
// float4 color;
float _distmax;
float _height;
float _ypos;
float3 _dimensions;
float3 _center;
float _crown;
float4x4 _matrix;
float4x4 _rGlove;
float4x4 _lGlove;
Texture2D tex; // : register(t0);
SamplerState tex_s; // : register(s0);
cbuffer BufferData : register(b3) {
float3 position;
float time;
};
struct vsIn {
float4 pos : SV_POSITION;
float3 norm : NORMAL0;
float2 uv : TEXCOORD0;
float4 col : COLOR0;
};
struct psIn {
float4 color : COLOR0;
float4 pos : SV_POSITION;
float3 norm : NORMAL1;
float2 uv : TEXCOORD0;
float3 campos : TEXCOORD1;
float3 world : TEXCOORD2;
uint view_id : SV_RenderTargetArrayIndex;
};
struct psOut {
float4 color : SV_Target;
float depth : SV_Depth;
};
psIn vs(vsIn input, uint id : SV_InstanceID) {
psIn o;
o.view_id = id % sk_view_count;
id = id / sk_view_count;
o.campos = sk_camera_pos[o.view_id].xyz;
o.world = mul(input.pos, sk_inst[id].world).xyz;
o.pos = mul(float4(o.world, 1), sk_viewproj[o.view_id]);
o.norm = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
o.uv = input.uv;
o.color = input.col;
return o;
}
float3 cross(float3 a, float3 b) {
return float3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}
float dot(float3 a, float3 b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
float sdSphere(float3 p, float s) {
return length(p) - s;
}
float sdPlane(float3 p, float3 n, float h) {
// n must be normalized
return dot(p,n) + h;
}
float sdBox(float3 p, float3 b) {
float3 q = abs(p) - b;
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
}
float sdOctahedron(float3 p, float s) {
p = abs(p);
return (p.x + p.y + p.z - s) * 0.57735027;
}
float sdBoxFrame(float3 p, float3 b, float e) {
p = abs(p) - b;
float3 q = abs(p + e) - e;
return min(
min(
length(max(float3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),
length(max(float3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)
),
length(max(float3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0)
);
}
float sdLink(float3 p, float le, float r1, float r2)
{
float3 q = float3(p.x, max(abs(p.z) - le, 0.0), p.y);
return length(float2(length(q.xy) - r1, q.z)) - r2;
}
float oriel(float3 ro, float3 rd) {
float dist = 0.0;
for (int i = 0; i < 256; i++) {
float3 pos = ro + dist * rd;
float step = sdBox(pos - _center, _dimensions / 2);
if (step < 0.0001 || dist > _distmax) break;
dist += step;
}
return dist;
}
float map(float3 pos) {
// pos.x = _center.x + pos.x;
// pos.y = _center.y + pos.y;
// pos.z = _center.z - pos.z;
// float3 spin = float3(sin(time), 0, cos(time)) * 0.5;
// float sphere = sdSphere(pos + spin - _center, 0.1);
// return sdLink(pos, 0.1, 0.1, 0.1);
// float octo = sdOctahedron(pos - _center - position, 0.2);
// float frame = sdBoxFrame(pos - _center - position, float3(0.06, 0.06, 0.06), 0.004);
// float orielFrame = sdBoxFrame(pos - _center, _dimensions / 2, 0.0006);
// float3 d = _dimensions / 2;
// d.y = _height;
// float orielCrown = sdBoxFrame(pos - _center, d, 0.000);
// float box = sdBox(pos, float3(0.1, 0.1, 0.1));
float3 posOriel = mul(float4(pos, 1), _matrix).xyz;
float oculus = sdLink(posOriel, 0.15, 0.125, 0.05);
float3 posLGlove = mul(float4(pos, 1), _lGlove).xyz;
float lglove = sdBox(posLGlove, float3(0.025, 0.1, 0.1) / 1.8);
float3 posRGlove = mul(float4(pos, 1), _rGlove).xyz;
float rglove = sdBox(posRGlove, float3(0.025, 0.1, 0.1) / 1.8);
// return lerp(sphere, octo, time);
float plane = sdPlane(pos + float3(0, 1.5, 0), float3(0, 1, 0), 0);
// float blendd = lerp(octo, frame, time);
return min(min(plane, oculus), min(lglove, rglove));
}
float raymarch(float3 ro, float3 rd) {
float dist = 0.0;
for (int i = 0; i < 256; i++) {
float3 pos = ro + dist * rd;
float step = map(pos);
if (step < 0.0001 || dist > _distmax) break;
dist += step;
}
return dist;
}
float3 calcNormal(float3 pos)
{
float2 e = float2(1.0, -1.0) * 0.5773;
float eps = 0.0005;
return normalize(
e.xyy * map(pos + e.xyy * eps) +
e.yyx * map(pos + e.yyx * eps) +
e.yxy * map(pos + e.yxy * eps) +
e.xxx * map(pos + e.xxx * eps)
);
}
float calcAO(float3 pos, float3 nor)
{
float occ = 0.0;
float sca = 1.0;
for (int i = 0; i < 5; i++) {
float h = 0.01 + 0.12 * float(i)/4.0;
float d = map(pos + h * nor).x;
occ += (h - d) * sca;
sca *= 0.95;
if (occ > 0.35) break;
}
return clamp(1.0 - 3.0 * occ, 0.0, 1.0) * (0.5 + 0.5 * nor.y);
}
float calcShadow(float3 pos, float3 light) {
float3 rd = normalize(light - pos);
float3 ro = pos + rd * 0.1;
float dist = raymarch(ro, rd);
return (float)(dist > _distmax);
}
psOut ps(psIn input) {
psOut result;
result.depth = input.pos.z;
float3 ro = input.campos; // ray origin
float3 rd = normalize(input.world - ro); // ray direction
float ol = oriel(ro, rd);
ro += ol * rd;
float dist = raymarch(ro, rd);
// float dist = raymarch(ro, rd);
// shading/lighting
float3 pos = ro + dist * rd;
float3 light = float3(0.0, 1.0, 0.0);
float3 lightDir = normalize(light - pos);
float3 col = float3(0.5, 0.75, 0.9);
if (dist == 0.0) {
col = float3(0.15, 0.15, 0.15);
}
if (dist < _distmax && dist > 0.0) {
float3 nor = calcNormal(pos);
float dif = clamp(dot(nor, lightDir), 0.0, 1.0);
float amb = 0.5 + 0.5 * dot(nor, lightDir);
float ao = calcAO(pos, nor);
float sh = calcShadow(pos, light);
dif *= ao * sh;
col = float3(0.1, 0.5, 0.3) * amb + float3(0.6, 0.8, 0.3) * dif;
if (pos.y > -1.0) {
// white
col = float3(0.8, 0.9, 0.9) * amb + float3(0.8, 1.0, 0.9) * dif;
}
// if (sdBox(pos - _center, _dimensions / 2) == 0.0) {
// float4 clipPos = mul(float4(pos, 1), sk_viewproj[input.view_id]);
// float near = 0.0;
// float far = _distmax;
// float a = (far + near) / (far - near);
// float b = 2.0 * far * near / (far - near);
// result.depth = a + b / clipPos.z;
// // result.depth = clipPos.z;
// }
}
// input.color = float4(col, 1);
if (input.world.y > (_center.y + _dimensions.y / 2.0 ) - _crown) {
float value = (col.r + col.r + col.g + col.g + col.g + col.b) / 6;
float lit = abs((1 - clamp(dot(input.norm, lightDir), -1.0, 1.0)) / 2);
value = (1 + lit + value) / 3;
col = lerp(float3(1, 1, 1) * value, col * lit, 0.333);
// col = float3(1 - col.r, 1 - col.g, 1 - col.b);
}
result.color = float4(col, 1);
// float4x4 worldToViewMatrix = sk_view[input.view_id];
// float4 viewIntersectionPos = worldToViewMatrix * float4(worldIntersection, 1.0);
// float n = 0.0f;
// float f = 200.0f;
// result.depth = (-viewIntersectionPos.z - n) / (f - n) * viewIntersectionPos.w;
// worldIntersection = float3(0.0);
// input.pos.w;
// result.depth = zc/wc;
// result.color.rgb = float3(zc/wc);
return result;
}

View file

@ -48,12 +48,14 @@ exec(vlai)
# bookmark(next page)
lift for all
glove visuals
*pull points
*mesh
double tap lift
set strength
*draw new line with reach cursor
&nbsp;

BIN
add/asteroids.glb Normal file

Binary file not shown.

BIN
add/colorball.glb Normal file

Binary file not shown.

View file

@ -1,41 +1,26 @@
#include "stereokit.hlsli"
// --name = dofdev/oriel
// float4 color;
float _distmax;
float _height;
float _ypos;
float3 _dimensions;
float3 _center;
float _crown;
float3 _dimensions;
float4x4 _matrix;
Texture2D tex; // : register(t0);
SamplerState tex_s; // : register(s0);
cbuffer BufferData : register(b3) {
float3 position;
float time;
};
struct vsIn {
float4 pos : SV_POSITION;
float3 norm : NORMAL0;
float2 uv : TEXCOORD0;
float4 col : COLOR0;
float4 position : SV_POSITION;
float3 normal : NORMAL;
float3 color : COLOR0;
};
struct psIn {
float4 position : SV_POSITION;
float3 world : WORLD;
float3 normal : NORMAL;
float4 color : COLOR0;
float4 pos : SV_POSITION;
float3 norm : NORMAL1;
float2 uv : TEXCOORD0;
float3 camdir : TEXCOORD0;
float3 campos : TEXCOORD1;
float3 world : TEXCOORD2;
uint view_id : SV_RenderTargetArrayIndex;
};
struct psOut {
float4 color : SV_Target;
float4 color : SV_TARGET;
float depth : SV_Depth;
};
@ -44,13 +29,13 @@ psIn vs(vsIn input, uint id : SV_InstanceID) {
o.view_id = id % sk_view_count;
id = id / sk_view_count;
o.camdir = sk_camera_dir[o.view_id].xyz;
o.campos = sk_camera_pos[o.view_id].xyz;
o.world = mul(input.pos, sk_inst[id].world).xyz;
o.pos = mul(float4(o.world, 1), sk_viewproj[o.view_id]);
o.norm = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
o.world = mul(input.position, sk_inst[id].world).xyz;
o.position = mul(float4(o.world, 1), sk_viewproj[o.view_id]);
o.normal = normalize(mul(input.normal, (float3x3)sk_inst[id].world));
o.color = float4(input.color * sk_inst[id].color.rgb, 1);
o.uv = input.uv;
o.color = input.col;
return o;
}
@ -62,190 +47,78 @@ float dot(float3 a, float3 b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
float sdSphere(float3 p, float s) {
return length(p) - s;
}
float sdPlane(float3 p, float3 n, float h) {
// n must be normalized
return dot(p,n) + h;
}
float sdBox(float3 p, float3 b) {
float3 q = abs(p) - b;
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
}
float sdOctahedron(float3 p, float s) {
p = abs(p);
return (p.x + p.y + p.z - s) * 0.57735027;
}
float sdBoxFrame(float3 p, float3 b, float e) {
p = abs(p) - b;
float3 q = abs(p + e) - e;
return min(
min(
length(max(float3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),
length(max(float3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)
),
length(max(float3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0)
);
}
float oriel(float3 ro, float3 rd) {
float dist = 0.0;
for (int i = 0; i < 256; i++) {
float3 pos = ro + dist * rd;
float step = sdBox(pos - _center, _dimensions / 2);
if (step < 0.0001 || dist > _distmax) break;
dist += step;
}
return dist;
}
float map(float3 pos) {
float3 posOriel = mul(float4(pos, 1), _matrix).xyz;
// pos.x = _center.x + pos.x;
// pos.y = _center.y + pos.y;
// pos.z = _center.z - pos.z;
// float3 spin = float3(sin(time), 0, cos(time)) * 0.5;
// float sphere = sdSphere(pos + spin - _center, 0.1);
// return sdLink(pos, 0.1, 0.1, 0.1);
// float octo = sdOctahedron(pos - _center - position, 0.2);
// float frame = sdBoxFrame(pos - _center - position, float3(0.06, 0.06, 0.06), 0.004);
// float orielFrame = sdBoxFrame(pos - _center, _dimensions / 2, 0.0006);
// float3 d = _dimensions / 2;
// d.y = _height;
// float orielCrown = sdBoxFrame(pos - _center, d, 0.000);
// float box = sdBox(pos, float3(0.1, 0.1, 0.1));
float box = sdBox(posOriel, float3(0.7, 0.015, 0.07));
// return lerp(sphere, octo, time);
float plane = sdPlane(pos + float3(0, 1.5, 0), float3(0, 1, 0), 0);
// float blendd = lerp(octo, frame, time);
return min(plane, box);
}
float raymarch(float3 ro, float3 rd) {
ro = mul(float4(ro, 1), _matrix).xyz;
rd = mul(float4(rd, 0), _matrix).xyz;
float dist = 0.0;
for (int i = 0; i < 256; i++) {
float3 pos = ro + dist * rd;
float step = map(pos);
if (step < 0.0001 || dist > _distmax) break;
float step = sdBox(pos, _dimensions / 2.0);
if (step < 0.0001 || dist > 100) break; // 100 == distmax
dist += step;
}
return dist;
}
float3 calcNormal(float3 pos)
{
float2 e = float2(1.0, -1.0) * 0.5773;
float eps = 0.0005;
return normalize(
e.xyy * map(pos + e.xyy * eps) +
e.yyx * map(pos + e.yyx * eps) +
e.yxy * map(pos + e.yxy * eps) +
e.xxx * map(pos + e.xxx * eps)
);
}
float calcAO(float3 pos, float3 nor)
{
float occ = 0.0;
float sca = 1.0;
for (int i = 0; i < 5; i++) {
float h = 0.01 + 0.12 * float(i)/4.0;
float d = map(pos + h * nor).x;
occ += (h - d) * sca;
sca *= 0.95;
if (occ > 0.35) break;
}
return clamp(1.0 - 3.0 * occ, 0.0, 1.0) * (0.5 + 0.5 * nor.y);
}
float calcShadow(float3 pos, float3 light) {
float3 rd = normalize(light - pos);
float3 ro = pos + rd * 0.1;
float dist = raymarch(ro, rd);
return (float)(dist > _distmax);
}
psOut ps(psIn input) {
psOut result;
result.depth = input.pos.z;
psOut o;
o.color = input.color;
o.depth = input.position.z;
float3 ro = input.campos;
float3 rd = normalize(input.world - ro);
// ro = ;
float ol = raymarch(ro, rd);
clip(100 - (ol + 1));
float3 ro = input.campos; // ray origin
float3 rd = normalize(input.world - ro); // ray direction
float ol = oriel(ro, rd);
ro += ol * rd;
float dist = raymarch(ro, rd);
// float dist = raymarch(ro, rd);
// shading/lighting
float3 pos = ro + dist * rd;
float3 light = float3(0.0, 1.0, 0.0);
float3 lightDir = normalize(light - pos);
float3 col = float3(0.5, 0.75, 0.9);
if (dist == 0.0) {
col = float3(0.15, 0.15, 0.15);
clip(distance(input.campos, input.world) - distance(input.campos, ro));
float t = 1 - (1 + dot(input.normal, normalize(input.world - _center))) / 2;
float3 light = lerp(float3(0.05, 0.05, 0.1), float3(0.95, 0.95, 0.9), t);
o.color = float4(o.color.rgb * light, 1);
// backface
if (dot(rd, input.normal) > 0) {
o.color = float4(0.5, 0.5, 0.5, 1);
}
if (dist < _distmax && dist > 0.0) {
float3 nor = calcNormal(pos);
float dif = clamp(dot(nor, lightDir), 0.0, 1.0);
float amb = 0.5 + 0.5 * dot(nor, lightDir);
float ao = calcAO(pos, nor);
float sh = calcShadow(pos, light);
dif *= ao * sh;
col = float3(0.1, 0.5, 0.3) * amb + float3(0.6, 0.8, 0.3) * dif;
// if (sdBox(pos - _center, _dimensions / 2) == 0.0) {
// float4 clipPos = mul(float4(pos, 1), sk_viewproj[input.view_id]);
// float near = 0.0;
// float far = _distmax;
// float a = (far + near) / (far - near);
// float b = 2.0 * far * near / (far - near);
// result.depth = a + b / clipPos.z;
// // result.depth = clipPos.z;
// }
}
// input.color = float4(col, 1);
if (input.world.y > (_center.y + _dimensions.y / 2.0 ) - _crown) {
float value = (col.r + col.r + col.g + col.g + col.g + col.b) / 6;
float lit = abs((1 - clamp(dot(input.norm, lightDir), -1.0, 1.0)) / 2);
value = (1 + lit + value) / 3;
col = lerp(float3(1, 1, 1) * value, col * lit, 0.333);
// col = float3(1 - col.r, 1 - col.g, 1 - col.b);
}
result.color = float4(col, 1);
// float4x4 worldToViewMatrix = sk_view[input.view_id];
// float4 viewIntersectionPos = worldToViewMatrix * float4(worldIntersection, 1.0);
// float n = 0.0f;
// float f = 200.0f;
// result.depth = (-viewIntersectionPos.z - n) / (f - n) * viewIntersectionPos.w;
// worldIntersection = float3(0.0);
// input.pos.w;
// result.depth = zc/wc;
// result.color.rgb = float3(zc/wc);
return result;
return o;
}
// float3 local = input.world - _center;
// clip(sign(_size - local.x) * sign(_size - local.y) * sign(_size - local.z));
// clip(sign(local.x + _size) * sign(local.y + _size) * sign(local.z + _size));
// scale RGB by perceived luminance
// float value = (c.r + c.r + c.g + c.g + c.g + c.b) / 6;
// c *= value;
// if (trunc(H * 100) % 2 == 0) {
// c = float3(1, 1, 1) - c;
// }
// float3 local = (input.world - _center) / _size * 2;
// float2 plane = float2(local.x, local.y);
// float H = acos(normalize(plane).y) / 3.141592653589793;
// if (sign(plane.x) < 0) {
// H = (1 - H + 1) / 2;
// } else {
// H = H / 2;
// }
// float C = distance(float2(0, 0), plane);
// float L = (1 + local.z) / 2;
// float3 c = HCLtoRGB(H, C, (L + 0.05) / 1.05);
// c *= L;

35
add/panes.hlsl Normal file
View file

@ -0,0 +1,35 @@
#include "stereokit.hlsli"
// --name = dofdev/panes
float4x4 _matrix;
struct vsIn {
float4 pos : SV_POSITION;
float3 norm : NORMAL;
};
struct psIn {
float4 pos : SV_POSITION;
float3 norm : NORMAL;
float4 world : WORLD;
float4 color : COLOR;
uint view_id : SV_RenderTargetArrayIndex;
};
psIn vs(vsIn input, uint id : SV_InstanceID) {
psIn o;
o.view_id = id % sk_view_count;
id = id / sk_view_count;
o.world = mul(input.pos, sk_inst[id].world);
o.pos = mul(o.world, sk_viewproj[o.view_id]);
o.norm = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
o.color = sk_inst[id].color;
return o;
}
float4 ps(psIn input) : SV_TARGET {
return input.color;
}

47
add/room.hlsl Normal file
View file

@ -0,0 +1,47 @@
#include "stereokit.hlsli"
//--name = dofdev/room
//--color:color = 1,1,1,1
//--tex_scale = 1
//--diffuse = white
float4 color;
float tex_scale;
Texture2D diffuse : register(t0);
SamplerState diffuse_s : register(s0);
struct vsIn {
float4 pos : SV_Position;
float3 norm : NORMAL0;
float2 uv : TEXCOORD0;
float4 col : COLOR0;
};
struct psIn {
float4 pos : SV_Position;
float2 uv : TEXCOORD0;
float4 color : COLOR0;
uint view_id : SV_RenderTargetArrayIndex;
};
psIn vs(vsIn input, uint id : SV_InstanceID) {
psIn o;
o.view_id = id % sk_view_count;
id = id / sk_view_count;
float4 world = mul(input.pos, sk_inst[id].world);
o.pos = mul(world, sk_viewproj[o.view_id]);
float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
o.uv = input.uv * tex_scale;
o.color = color * input.col * sk_inst[id].color;
// o.color.rgb *= Lighting(normal);
return o;
}
float4 ps(psIn input) : SV_TARGET {
float4 col = diffuse.Sample(diffuse_s, input.uv);
float value = (col.r + col.r + col.g + col.g + col.g + col.b) / 6;
return float4(value, value, value, 1);
}

BIN
add/room/BestRoom0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
add/room/BestRoom1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

BIN
add/room/BestRoom2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
add/room/BestRoom3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
add/room/BestRoom4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
add/room/BestRoom5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
add/room/BestRoom6.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
add/room/BestRoom7.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
add/room/BestRoom8.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
add/room/BestRoom9.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

11
add/room/license.txt Normal file
View file

@ -0,0 +1,11 @@
Model Information:
* title: White Hart House
* source: https://sketchfab.com/3d-models/white-hart-house-7f4084ed27634b0596061a6f9811cb64
* author: 9of9 (https://sketchfab.com/9of9)
Model License:
* license type: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
* requirements: Author must be credited. Commercial use is allowed.
If you use this 3D model in your project be sure to copy paste this credit wherever you share it:
This work is based on "White Hart House" (https://sketchfab.com/3d-models/white-hart-house-7f4084ed27634b0596061a6f9811cb64) by 9of9 (https://sketchfab.com/9of9) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)

BIN
add/room/room.glb Normal file

Binary file not shown.

54
add/wireframe.hlsl Normal file
View file

@ -0,0 +1,54 @@
#include "stereokit.hlsli"
// --name = dofdev/wireframe
float3 _rGlovePos;
struct vsIn {
float4 pos : SV_POSITION;
float3 norm : NORMAL;
};
struct psIn {
float4 pos : SV_POSITION;
float4 col : COLOR;
float4 world : WORLD;
uint view_id : SV_RenderTargetArrayIndex;
};
psIn vs(vsIn input, uint id : SV_InstanceID) {
psIn o;
o.view_id = id % sk_view_count;
id = id / sk_view_count;
float3 norm = normalize(input.norm);
// input.pos.xyz += norm * 0.01;
// wirefame
// o.pos = mul(sk_view[o.view_id], input.pos);
// float4 viewPosition = mul(input.pos, sk_view[o.view_id]);
// o.pos = mul(viewPosition, sk_proj[o.view_id]);
o.world = mul(input.pos, sk_inst[id].world);
o.pos = mul(o.world, sk_viewproj[o.view_id]);
o.col = sk_inst[id].color;
return o;
}
float4 ps(psIn input) : SV_TARGET {
float4 c = input.col;
float3 rLocal = (input.world.xyz - _rGlovePos) * 6;
c.r = 1 - min(abs(rLocal.x), 1.0);
c.g = 1 - min(abs(rLocal.y), 1.0);
c.b = 1 - min(abs(rLocal.z), 1.0);
float m = min(c.r, min(c.g, c.b));
c.rgb *= m;
// if (m == 0) {
// }
return c;
}

View file

@ -155,8 +155,8 @@ public class Glove {
}
Lines.Add(linePoints);
mesh.Draw(mat, glove.ToMatrix(new Vec3(0.025f, 0.025f, 0.025f) / 3));
mesh.Draw(mat, virtualGlove.ToMatrix(new Vec3(0.025f, 0.1f, 0.1f) / 3));
mesh.Draw(mat, glove.ToMatrix(new Vec3(0.02f, 0.08f, 0.08f) / 1));
mesh.Draw(mat, virtualGlove.ToMatrix(new Vec3(0.025f, 0.1f, 0.1f) / 1));
// ModelNode top = model.FindNode("Top");

View file

@ -11,7 +11,7 @@ if (!SK.Initialize(settings))
Environment.Exit(1);
Input.HandSolid(Handed.Max, false);
// Input.HandVisible(Handed.Max, false);
Input.HandVisible(Handed.Max, false);
// TextStyle style = Text.MakeStyle(Font.FromFile("DMMono-Regular.ttf"), 0.1f, Color.White);
Monolith mono = new Monolith();
@ -68,6 +68,9 @@ public class Monolith {
public Glove Glove(bool chirality) {
return chirality ? rGlove : lGlove;
}
public Oriel oriel = new Oriel();
// Oriel otherOriel = new Oriel(this);
public ColorCube colorCube = new ColorCube();
public Block[] blocks;
public BlockCon rBlock, lBlock;
@ -109,11 +112,6 @@ public class Monolith {
Vec3 pos = new Vec3(0, 0, 0);
Vec3 vel = new Vec3(0, 0, 0);
Oriel oriel = new Oriel();
oriel.Start(3);
// Oriel otherOriel = new Oriel();
// otherOriel.Start(4);
Vec3 oldLPos = Vec3.Zero;
while (SK.Step(() => {
@ -316,7 +314,7 @@ public class Monolith {
// COLOR CUBE
// COLOR CUBE (RGB)
// reveal when palm up
float reveal = lCon.device.pose.Right.y * 1.666f;
float look = 1 - Math.Clamp((1 - Math.Clamp(Vec3.Dot((lCon.device.pose.position - Input.Head.position).Normalized, Input.Head.Forward), 0f, 1f)) * 5f, 0f, 1f);
@ -333,24 +331,51 @@ public class Monolith {
colorCube.cursor.y = Math.Clamp(colorCube.cursor.y, -1, 1);
colorCube.cursor.z = Math.Clamp(colorCube.cursor.z, -1, 1);
}
colorCube.Step();
// colorCube.Step();
}
oldLPos = lCon.device.pose.position;
oriel.Step(rGlove.virtualGlove.position, lGlove.virtualGlove.position);
oriel.Step(this);
// Matrix orbitMatrix = OrbitalView.transform;
// cube.Step(Matrix.S(Vec3.One * 0.2f) * orbitMatrix);
// Default.MaterialHand["color"] = cube.color;
scene.Step();
net.me.Step(this);
net.send = true;
// if (rCon)
ShowWindowButton();
}));
SK.Shutdown();
}
Pose windowPoseButton = new Pose(0, 0, 0, Quat.Identity);
void ShowWindowButton() {
UI.WindowBegin("Window Button", ref windowPoseButton);
if (UI.Button("Reset Oriel Quat")) {
oriel.ori = Quat.Identity;
}
if (UI.Button("Draw Oriel Axis")) {
oriel.drawAxis = !oriel.drawAxis;
}
UI.WindowEnd();
}
}
public class Lerper {
@ -440,4 +465,36 @@ public static class PullRequest {
}
meshCube.Draw(mat, m, color);
}
public static Mesh GetMesh(this Model model, string name) {
for (int i = 0; i < model.Nodes.Count; i++) {
if (model.Nodes[i].Name == name) {
return model.Nodes[i].Mesh;
}
}
Console.WriteLine("Mesh not found: " + name);
return Mesh.Quad;
}
public static void SetMat(this Material mat, int offset, Cull cull, bool depthWrite) {
mat.QueueOffset = offset;
mat.FaceCull = cull;
mat.DepthWrite = depthWrite;
}
public static Vec3 RandomInCube(Vec3 center, float size) {
Random r = new Random();
return center + new Vec3(
(r.NextSingle() - 0.5f) * size,
(r.NextSingle() - 0.5f) * size,
(r.NextSingle() - 0.5f) * size
);
}
static Bounds _bounds = new Bounds();
public static bool ActuallyContains(this Bounds bounds, Quat ori, Vec3 pos, float radius) {
_bounds.dimensions = bounds.dimensions;
Vec3 p = ori.Inverse * (pos - bounds.center);
return _bounds.Contains(p, p, radius);
}
}

View file

@ -1,102 +1,257 @@
using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Generic;
using StereoKit;
[StructLayout(LayoutKind.Sequential)]
struct BufferData {
public Vec3 position;
// public Vec3[] tri;
public float time;
}
public class Oriel {
public Bounds bounds;
Material mat = new Material(Shader.FromFile("oriel.hlsl"));
Mesh mesh = Default.MeshCube;
static Material matFrame = new Material(Shader.FromFile("wireframe.hlsl"));
static Material matPanes = new Material(Shader.FromFile("panes.hlsl"));
static Material matOriel = new Material(Shader.FromFile("oriel.hlsl"));
static Model model = Model.FromFile("colorball.glb");
Mesh meshCube, meshFrame;
public Bounds bounds; Vec3 _dimensions;
public Quat ori;
public float crown = 0.0666f;
public bool drawAxis;
bool scalingOriel = false;
bool draggingOriel = false;
Vec3 orielOffset = Vec3.Zero;
bool adjusting = false;
// bool scalingOriel = false;
// bool draggingOriel = false;
// bool rotatingOriel = false;
Quat qOffset = Quat.Identity;
Vec3 vOffset = Vec3.Zero;
Vec3 anchor = Vec3.Zero;
Matrix mOffset = Matrix.Identity;
MaterialBuffer<BufferData> buffer;
public Oriel() {
bounds = new Bounds(
Input.Head.position + new Vec3(0, 0f, -1.5f),
new Vec3(0.8f, 0.5f, 0.5f)
);
public void Start(int bufferIndex) {
bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f));
buffer = new MaterialBuffer<BufferData>(bufferIndex);
_dimensions = bounds.dimensions;
ori = Quat.Identity;
matFrame.SetMat(102, Cull.None, true);
matPanes.SetMat(100, Cull.Front, false);
matOriel.SetMat(101, Cull.None, true);
meshFrame = model.GetMesh("Wireframe");
meshCube = Mesh.Cube;
Gen();
}
BufferData data = new BufferData();
public void Step(Vec3 cursor0, Vec3 cursor3) {
Controller rCon = Input.Controller(Handed.Right);
Controller lCon = Input.Controller(Handed.Left);
Vec3 detect = Vec3.Zero;
int detectCount = 0;
public void Step(Monolith mono) {
Matrix matrix = Matrix.TR(bounds.center, ori).Inverse;
if (rCon.trigger > 0.5f && lCon.trigger > 0.5f) {
if (!scalingOriel) {
if (bounds.Contains(cursor0) || bounds.Contains(cursor3)) {
scalingOriel = true;
Vec3 rGlovePos = mono.rGlove.virtualGlove.position;
// Vec3 lGlovePos = mono.lGlove.virtualGlove.position;
// face detection = (1 axis)
// edge detection = (2 axis)
// corner detection = (3 axis)
Vec3 localPos = matrix.Transform(rGlovePos);
if (!mono.rCon.triggerBtn.held) {
Vec3 newDetect = Vec3.Zero;
if ((_dimensions.x / 2) - MathF.Abs(localPos.x) < 0.1f) newDetect.x = 1 * MathF.Sign(localPos.x);
if ((_dimensions.y / 2) - MathF.Abs(localPos.y) < 0.1f) newDetect.y = 1 * MathF.Sign(localPos.y);
if ((_dimensions.z / 2) - MathF.Abs(localPos.z) < 0.1f) newDetect.z = 1 * MathF.Sign(localPos.z);
if (newDetect.x != detect.x || newDetect.y != detect.y || newDetect.z != detect.z) {
detect = newDetect;
detectCount = (int)(MathF.Abs(detect.x) + MathF.Abs(detect.y) + MathF.Abs(detect.z));
Console.WriteLine(detectCount + ": " + detect);
}
if (!bounds.ActuallyContains(ori, rGlovePos, 0.1f) || bounds.ActuallyContains(ori, rGlovePos, 0f)) {
detect = Vec3.Zero;
detectCount = 0;
}
vOffset = rGlovePos - bounds.center;
mOffset = matrix;
// qOffset = Quat.LookAt(Vec3.Zero, vOffset.Normalized);
anchor = bounds.center + ori * -(detect * bounds.dimensions / 2);
adjusting = false;
} else {
bounds.center = Vec3.Lerp(cursor0, cursor3, 0.5f);
float distX = Math.Abs(cursor0.x - cursor3.x);
float distY = Math.Abs(cursor0.y - cursor3.y);
float distZ = Math.Abs(cursor0.z - cursor3.z);
if (detectCount == 1) { // Move
bounds.center = rGlovePos - vOffset;
} else if (detectCount == 2) { // Rotate
localPos = mOffset.Transform(rGlovePos);
Vec3 dir = new Vec3(
detect.x == 0 ? 0 : localPos.x,
detect.y == 0 ? 0 : localPos.y,
detect.z == 0 ? 0 : localPos.z
);
Vec3 up = new Vec3(
detect.x == 0 ? 1 : 0,
detect.y == 0 ? 1 : 0,
detect.z == 0 ? 1 : 0
);
// Quat q = Quat.FromAngles(up * Vec2.AngleBetween(dir.XZ, detect.XZ));
// a quick reset function, as the rotation gets fucked
Quat q = Quat.LookAt(Vec3.Zero, dir, up);
if (!adjusting) {
qOffset = (q.Inverse * ori).Normalized;
adjusting = true;
} else {
ori = (q * qOffset).Normalized;
}
} else if (detectCount == 3) { // Scale
Vec3 localAnchor = matrix.Transform(anchor);
float distX = Math.Abs(localAnchor.x - localPos.x);
float distY = Math.Abs(localAnchor.y - localPos.y);
float distZ = Math.Abs(localAnchor.z - localPos.z);
bounds.dimensions = new Vec3(distX, distY, distZ);
bounds.center = Vec3.Lerp(anchor, rGlovePos, 0.5f);
}
} else {
scalingOriel = false;
}
if (!scalingOriel && rCon.trigger > 0.5f) {
if (!draggingOriel) {
bool inCrown = cursor0.y > (bounds.center.y + bounds.dimensions.y / 2.0) - crown;
if (bounds.Contains(cursor0) && inCrown) {
orielOffset = cursor0 - bounds.center;
draggingOriel = true;
}
} else {
bounds.center = cursor0 - orielOffset;
}
} else {
draggingOriel = false;
}
// meet the user halfway, as there is a lot of context provided with where they grab the oriel
// instead of a discrete handle and interaction
data.position = cursor0;
data.time = (float)Time.Total;
buffer.Set(data);
Matrix matrix = Matrix.TR(
bounds.center,
Quat.FromAngles(0, Time.Totalf * 12, 0).Normalized
).Inverse;
// matrix. = (float)Math.Sin(Time.Elapsedf);
mat["_matrix"] = (Matrix)System.Numerics.Matrix4x4.Transpose(matrix);
// mat.SetMatrix("_matrix", matrix);
// circle around center
// bounds.center = Quat.FromAngles(0, 0, Time.Totalf * 60) * Vec3.Up * 0.3f;
// bounds.dimensions = _dimensions * (1f + (MathF.Sin(Time.Totalf * 3) * 0.3f));
// bounds.center = Vec3.Forward * 3 + Quat.FromAngles(0, 0, Time.Totalf * 60) * Vec3.Up * 0.3f;
// bounds.dimensions.y = _dimensions.y * (1f + (MathF.Sin(Time.Totalf * 3) * 0.6f));
// bounds.center.y = (float)Math.Sin(Time.Totalf * 3) * 0.3f;
mat.FaceCull = Cull.Front;
// mat.DepthTest = DepthTest.Always;
// mat.QueueOffset = 1000;
matrix = Matrix.TR(bounds.center, ori).Inverse;
mat.SetFloat("_distmax", 1000);
mat.SetVector("_dimensions", bounds.dimensions);
mat.SetVector("_center", bounds.center);
mat.SetFloat("_crown", crown);
Matrix m = Matrix.TRS(bounds.center, Quat.Identity, bounds.dimensions);
Pose head = Input.Head;
mesh.Draw(mat, m);
matFrame.Wireframe = true;
matFrame.DepthTest = DepthTest.Always;
matFrame.SetVector("_rGlovePos", rGlovePos);
meshFrame.Draw(matFrame,
Matrix.TRS(bounds.center, ori, bounds.dimensions),
new Color(0.1f, 0.1f, 0.1f)
);
if (detectCount > 0) {
meshCube.Draw(Material.Default,
Matrix.TS(detect * (bounds.dimensions / 2), Vec3.One * 0.01f) * matrix.Inverse
);
}
// matPanes.DepthTest = DepthTest.Greater;
matPanes["_matrix"] = (Matrix)System.Numerics.Matrix4x4.Transpose(matrix);
meshCube.Draw(matPanes,
Matrix.TRS(bounds.center, ori, bounds.dimensions),
new Color(0.1f, 0.1f, 0.4f)
);
matOriel.SetVector("_center", bounds.center);
matOriel.SetVector("_dimensions", bounds.dimensions);
matOriel["_matrix"] = (Matrix)System.Numerics.Matrix4x4.Transpose(matrix);
Matrix orielSimMatrix = Matrix.TR(new Vec3(0, -bounds.dimensions.y / 2, 0), Quat.Identity).Inverse;
if (drawAxis) {
meshAxis.Draw(matOriel,
Matrix.TRS(Vec3.Zero, Quat.Identity, Vec3.One * 0.06f) * orielSimMatrix.Inverse * matrix.Inverse,
Color.White
);
}
Mesh.Quad.Draw(matOriel,
Matrix.TRS(Vec3.Zero, Quat.FromAngles(90, 0, 0), Vec3.One * 2f) * orielSimMatrix.Inverse * matrix.Inverse,
new Color(0.3f, 0.9f, 0.3f)
);
meshCube.Draw(matOriel,
mono.rGlove.virtualGlove.ToMatrix(new Vec3(0.025f, 0.1f, 0.1f) * 1.05f),
new Color(0.5f, 0.5f, 0.9f)
);
// draw relative to oriel matrix
// for (int i = 0; i < asteroids.Count; i++) {
// Asteroid asteroid = asteroids[i];
// asteroid.pose.orientation = Quat.FromAngles(Time.Elapsedf * 10 * asteroid.scale, 0, 0) * asteroid.pose.orientation;
// meshAsteroid.Draw(matOriel,
// asteroid.pose.ToMatrix(Vec3.One * asteroid.scale) * matrix.Inverse,
// Color.White * 0.32f
// );
// }
for (int i = 0; i < enemies.Count; i++) {
Solid enemy = enemies[i];
meshCube.Draw(matOriel,
Matrix.TRS((enemy.GetPose().position - simOffset) / 10, enemy.GetPose().orientation, new Vec3(0.4f, 1f, 0.2f) / 10) * orielSimMatrix.Inverse * matrix.Inverse,
Color.White * 0.32f
);
}
}
Solid ground;
List<Solid> enemies = new List<Solid>();
Vec3 simOffset = new Vec3(0, 100, 0);
Mesh meshAsteroid, meshAxis;
static Model modelAsteroids = Model.FromFile("asteroids.glb");
class Asteroid {
public Pose pose;
public float scale;
public Asteroid(Pose pose, float scale) {
this.pose = pose;
this.scale = scale;
}
}
List<Asteroid> asteroids = new List<Asteroid>();
void Gen() {
meshAxis = model.GetMesh("Axis");
meshAsteroid = modelAsteroids.GetMesh("1 Meteor");
asteroids.Clear();
Random random = new Random();
// for (int i = 0; i < 128; i++) {
// Pose pose = new Pose(
// PullRequest.RandomInCube(Vec3.Up * bounds.dimensions.y * 1, bounds.dimensions.x * 2),
// Quat.FromAngles(
// random.Next(360),
// random.Next(360),
// random.Next(360)
// )
// );
// asteroids.Add(new Asteroid(pose, 0.1f + random.NextSingle() * 0.4f));
// }
ground = new Solid(simOffset, Quat.Identity, SolidType.Immovable);
ground.AddBox(new Vec3(20, 1, 20), 1, new Vec3(0, -0.5f, 0));
for (int i = 0; i < 32; i++) {
Solid solid = new Solid(
simOffset + Vec3.Up * i,
Quat.Identity,
SolidType.Normal
);
solid.AddBox(new Vec3(0.4f, 1f, 0.2f), 1);
enemies.Add(solid);
}
}
}

View file

@ -4,11 +4,14 @@ using StereoKit;
public class Scene {
Monolith mono;
Material matFloor = new Material(Shader.Default);
Model room = Model.FromFile("room/room.glb", Shader.FromFile("room.hlsl"));
Solid floor;
public Scene(Monolith mono) {
this.mono = mono;
floor = new Solid(Vec3.Up * -1.5f, Quat.Identity, SolidType.Immovable);
Console.WriteLine("DSJLFDSFJKJSFD:KJLF: " + room.Nodes.Count);
floor = new Solid(World.BoundsPose.position, Quat.Identity, SolidType.Immovable);
scale = 64f;
floorScale = new Vec3(scale, 0.1f, scale);
floor.AddBox(floorScale);
@ -28,6 +31,9 @@ public class Scene {
public void Step() {
PullRequest.BlockOut(floor.GetPose().ToMatrix(floorScale), Color.White * 0.666f, matFloor);
// PullRequest.BlockOut(floor.GetPose().ToMatrix(floorScale), Color.White * 0.333f, matFloor);
room.Draw(Matrix.TRS(new Vec3(0, World.BoundsPose.position.y, -1), Quat.Identity, Vec3.One));
}
}

View file

@ -21,11 +21,17 @@
<ItemGroup>
<None Remove="add/oriel.hlsl" />
<None Remove="add/colorcube.hlsl" />
<None Remove="add/panes.hlsl" />
<None Remove="add/wireframe.hlsl" />
<None Remove="add/room.hlsl" />
</ItemGroup>
<ItemGroup>
<SKShader Include="add/oriel.hlsl" />
<SKShader Include="add/colorcube.hlsl" />
<SKShader Include="add/panes.hlsl" />
<SKShader Include="add/wireframe.hlsl" />
<SKShader Include="add/room.hlsl" />
</ItemGroup>
</Project>

BIN
res/asteroids.blend Normal file

Binary file not shown.

BIN
res/colorball.blend Normal file

Binary file not shown.

BIN
res/room.blend Normal file

Binary file not shown.