Initialer Upload neues Unity-Projekt
This commit is contained in:
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Oculus.Interaction.Demo
|
||||
{
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
public class MeshBlit : MonoBehaviour
|
||||
{
|
||||
private static int MAIN_TEX = Shader.PropertyToID("_MainTex");
|
||||
|
||||
public Material material;
|
||||
public RenderTexture renderTexture;
|
||||
|
||||
[SerializeField]
|
||||
private float _blitsPerSecond = -1;
|
||||
public float BlitsPerSecond
|
||||
{
|
||||
get
|
||||
{
|
||||
return _blitsPerSecond;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetBlitsPerSecond(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Mesh _mesh;
|
||||
private WaitForSeconds _waitForSeconds;
|
||||
|
||||
private Mesh Mesh => _mesh ? _mesh : _mesh = GetComponent<MeshFilter>().sharedMesh;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
SetBlitsPerSecond(_blitsPerSecond);
|
||||
StartCoroutine(BlitRoutine());
|
||||
|
||||
IEnumerator BlitRoutine()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return _waitForSeconds;
|
||||
Blit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Blit()
|
||||
{
|
||||
if (renderTexture == null)
|
||||
{
|
||||
throw new NullReferenceException("MeshBlit.Blit must have a RenderTexture assigned");
|
||||
}
|
||||
if (material == null)
|
||||
{
|
||||
throw new NullReferenceException("MeshBlit.Blit must have a Material assigned");
|
||||
}
|
||||
if (Mesh == null)
|
||||
{
|
||||
throw new NullReferenceException("MeshBlit.Blit's MeshFilter has no mesh");
|
||||
}
|
||||
|
||||
RenderTexture temp = RenderTexture.GetTemporary(renderTexture.descriptor);
|
||||
Graphics.Blit(renderTexture, temp);
|
||||
|
||||
material.SetTexture(MAIN_TEX, temp);
|
||||
|
||||
var previous = RenderTexture.active;
|
||||
RenderTexture.active = renderTexture;
|
||||
material.SetPass(0);
|
||||
Graphics.DrawMeshNow(Mesh, transform.localToWorldMatrix);
|
||||
RenderTexture.active = previous;
|
||||
|
||||
material.SetTexture(MAIN_TEX, null);
|
||||
RenderTexture.ReleaseTemporary(temp);
|
||||
}
|
||||
|
||||
private void SetBlitsPerSecond(float value)
|
||||
{
|
||||
_blitsPerSecond = value;
|
||||
_waitForSeconds = value > 0 ? new WaitForSeconds(1 / _blitsPerSecond) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f38a2c2a6f2edf246a68b41b406dd964
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d03fabf79ac272479773d0172fb4740
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/Interaction/Samples/Scripts/HandGrabUse/Effects/WaterSpray/Drops_Tiled_Normal-Map.png
(Stored with Git LFS)
Normal file
BIN
Assets/Oculus/Interaction/Samples/Scripts/HandGrabUse/Effects/WaterSpray/Drops_Tiled_Normal-Map.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,97 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06aafc7fcb186454893618a0b137089b
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 1
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
// @lint-ignore SOCIALVRTEXTUREIMPORTS
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,88 @@
|
||||
/************************************************************************************
|
||||
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
||||
|
||||
Your use of this SDK or tool is subject to the Oculus SDK License Agreement, available at
|
||||
https://developer.oculus.com/licenses/oculussdk/
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Utilities SDK distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
ANY KIND, either express or implied. See the License for the specific language governing
|
||||
permissions and limitations under the License.
|
||||
************************************************************************************/
|
||||
|
||||
Shader "MeshBlit/MeshBlitStamp"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[NoScaleOffset] _Stamp("Stamp", 2D) = "black" {}
|
||||
_StampMultipler("Stamp Multipler", Float) = 1
|
||||
[Enum(UV0,0,UV1,1)] _UV("UV Set", Float) = 1
|
||||
|
||||
[HideInInspector]_MainTex("Texture", 2D) = "black" {}
|
||||
[HideInInspector]_Subtract("Subtract", float) = 0
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float4 normal : NORMAL;
|
||||
float2 uv0 : TEXCOORD0;
|
||||
float2 uv1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 stampUV : TEXCOORD1;
|
||||
float3 normalWS : TEXCOORD4;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
float4x4 _StampMatrix;
|
||||
sampler2D _MainTex;
|
||||
sampler2D _Stamp;
|
||||
half _StampMultipler;
|
||||
float _Subtract;
|
||||
half _UV;
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o;
|
||||
float2 uv = (_UV == 0) ? v.uv0 : v.uv1;
|
||||
o.uv = uv;
|
||||
#if SHADER_API_D3D11
|
||||
uv.y = 1 - uv.y;
|
||||
#endif
|
||||
o.vertex = float4(uv * 2 - 1, 0.5, 1);
|
||||
float4 positionWS = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1));
|
||||
o.stampUV = mul(_StampMatrix, positionWS);
|
||||
o.normalWS = normalize(UnityObjectToWorldNormal(v.normal)); //TODO dont include the stamp on backfaces
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float4 col = tex2D(_MainTex, i.uv);
|
||||
col = max(0, col - _Subtract);
|
||||
|
||||
float2 stampUV = saturate((i.stampUV.xy / i.stampUV.w) * 0.5 + 0.5);
|
||||
half4 stamp = tex2D(_Stamp, stampUV);
|
||||
col += stamp * _StampMultipler;
|
||||
col = saturate(col);
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14c4f10921fa2ed46b4a9be3c07abeee
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures:
|
||||
- _Stamp: {instanceID: 0}
|
||||
- _MainTex: {instanceID: 0}
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using Oculus.Interaction.HandGrab;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Oculus.Interaction.Demo
|
||||
{
|
||||
public class WaterSpray : MonoBehaviour, IHandGrabUseDelegate
|
||||
{
|
||||
public enum NozzleMode
|
||||
{
|
||||
Spray,
|
||||
Stream
|
||||
}
|
||||
|
||||
[Header("Input")]
|
||||
[SerializeField]
|
||||
private Transform _trigger;
|
||||
[SerializeField]
|
||||
private Transform _nozzle;
|
||||
[SerializeField]
|
||||
private AnimationCurve _triggerRotationCurve;
|
||||
[SerializeField]
|
||||
private SnapAxis _axis = SnapAxis.X;
|
||||
[SerializeField]
|
||||
[Range(0f, 1f)]
|
||||
private float _releaseThresold = 0.3f;
|
||||
[SerializeField]
|
||||
[Range(0f, 1f)]
|
||||
private float _fireThresold = 0.9f;
|
||||
[SerializeField]
|
||||
private float _triggerSpeed = 3f;
|
||||
[SerializeField]
|
||||
private AnimationCurve _strengthCurve = AnimationCurve.EaseInOut(0f,0f,1f,1f);
|
||||
|
||||
[Header("Output")]
|
||||
[SerializeField, Tooltip("Masks the Raycast used to find objects to make wet")]
|
||||
private LayerMask _raycastLayerMask = ~0;
|
||||
[SerializeField, Tooltip("The spread angle when spraying, larger values will make a larger area wet")]
|
||||
private float _spraySpreadAngle = 40;
|
||||
[SerializeField, Tooltip("The spread angle when using stream, larger values will make a larger area wet")]
|
||||
private float _streamSpreadAngle = 4;
|
||||
[SerializeField]
|
||||
private float _sprayStrength = 1.5f;
|
||||
[SerializeField]
|
||||
private int _sprayHits = 6;
|
||||
[SerializeField]
|
||||
private float _sprayRandomness = 6f;
|
||||
[SerializeField, Tooltip("The max distance of the spray, controls the raycast and shader")]
|
||||
private float _maxDistance = 2;
|
||||
[SerializeField]
|
||||
private float _dryingSpeed = 0.1f;
|
||||
[SerializeField, Tooltip("Material for applying a stamp, should using the MeshBlitStamp shader or similar")]
|
||||
private Material _sprayStampMaterial = null;
|
||||
[SerializeField, Tooltip("When not null, will be set as the '_WetBumpMap' property on wet renderers")]
|
||||
private Texture _waterBumpOverride = null;
|
||||
|
||||
[SerializeField]
|
||||
private UnityEvent WhenSpray;
|
||||
[SerializeField]
|
||||
private UnityEvent WhenStream;
|
||||
|
||||
private static readonly int WET_MAP_PROPERTY = Shader.PropertyToID("_WetMap");
|
||||
private static readonly int STAMP_MULTIPLIER_PROPERTY = Shader.PropertyToID("_StampMultipler");
|
||||
private static readonly int SUBTRACT_PROPERTY = Shader.PropertyToID("_Subtract");
|
||||
private static readonly int WET_BUMPMAP_PROPERTY = Shader.PropertyToID("_WetBumpMap");
|
||||
private static readonly int STAMP_MATRIX_PROPERTY = Shader.PropertyToID("_StampMatrix");
|
||||
|
||||
private static readonly WaitForSeconds WAIT_TIME = new WaitForSeconds(0.1f);
|
||||
|
||||
private bool _wasFired = false;
|
||||
private float _dampedUseStrength = 0;
|
||||
private float _lastUseTime;
|
||||
|
||||
#region input
|
||||
|
||||
private void SprayWater()
|
||||
{
|
||||
NozzleMode mode = GetNozzleMode();
|
||||
if (mode == NozzleMode.Spray)
|
||||
{
|
||||
Spray();
|
||||
WhenSpray?.Invoke();
|
||||
}
|
||||
else if (mode == NozzleMode.Stream)
|
||||
{
|
||||
Stream();
|
||||
WhenStream?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTriggerRotation(float progress)
|
||||
{
|
||||
float value = _triggerRotationCurve.Evaluate(progress);
|
||||
Vector3 angles = _trigger.localEulerAngles;
|
||||
if ((_axis & SnapAxis.X) != 0)
|
||||
{
|
||||
angles.x = value;
|
||||
}
|
||||
if ((_axis & SnapAxis.Y) != 0)
|
||||
{
|
||||
angles.y = value;
|
||||
}
|
||||
if ((_axis & SnapAxis.Z) != 0)
|
||||
{
|
||||
angles.z = value;
|
||||
}
|
||||
_trigger.localEulerAngles = angles;
|
||||
}
|
||||
|
||||
|
||||
private NozzleMode GetNozzleMode()
|
||||
{
|
||||
int rotations = ((int)_nozzle.localEulerAngles.z + 45) / 90;
|
||||
if (rotations % 2 == 0)
|
||||
{
|
||||
return NozzleMode.Spray;
|
||||
}
|
||||
return NozzleMode.Stream;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region output
|
||||
private void Spray()
|
||||
{
|
||||
StartCoroutine(StampRoutine(_sprayHits, _sprayRandomness, _spraySpreadAngle, _sprayStrength));
|
||||
}
|
||||
|
||||
private void Stream()
|
||||
{
|
||||
StartCoroutine(StampRoutine(_sprayHits, 0, _streamSpreadAngle, _sprayStrength));
|
||||
}
|
||||
|
||||
private IEnumerator StampRoutine(int stampCount, float randomness, float spread, float strength)
|
||||
{
|
||||
StartStamping();
|
||||
Pose originalPose = _nozzle.GetPose();
|
||||
for (int i = 0; i < stampCount; i++)
|
||||
{
|
||||
yield return WAIT_TIME;
|
||||
Pose randomPose = originalPose;
|
||||
randomPose.rotation =
|
||||
randomPose.rotation *
|
||||
Quaternion.Euler(
|
||||
Random.Range(-randomness, randomness),
|
||||
Random.Range(-randomness, randomness),
|
||||
0f);
|
||||
|
||||
Stamp(randomPose, _maxDistance, spread, strength);
|
||||
}
|
||||
StartDrying();
|
||||
}
|
||||
|
||||
private void StartStamping()
|
||||
{
|
||||
_sprayStampMaterial.SetFloat(SUBTRACT_PROPERTY, 0);
|
||||
}
|
||||
|
||||
private void StartDrying()
|
||||
{
|
||||
_sprayStampMaterial.SetMatrix(STAMP_MATRIX_PROPERTY, Matrix4x4.zero);
|
||||
_sprayStampMaterial.SetFloat(SUBTRACT_PROPERTY, _dryingSpeed);
|
||||
}
|
||||
|
||||
private void Stamp(Pose pose, float maxDistance, float angle, float strength)
|
||||
{
|
||||
_sprayStampMaterial.SetMatrix(STAMP_MATRIX_PROPERTY, CreateStampMatrix(pose, angle));
|
||||
_sprayStampMaterial.SetFloat(STAMP_MULTIPLIER_PROPERTY, strength);
|
||||
|
||||
float radius = Mathf.Tan(Mathf.Deg2Rad * angle / 2) * maxDistance;
|
||||
Vector3 startPoint = pose.position + pose.forward * radius;
|
||||
Vector3 endPoint = pose.position + pose.forward * maxDistance;
|
||||
int hitCount = Physics.OverlapCapsuleNonAlloc(startPoint, endPoint, radius, NonAlloc._overlapResults, _raycastLayerMask.value, QueryTriggerInteraction.Ignore);
|
||||
HashSet<Transform> roots = NonAlloc.GetRootsFromOverlapResults(hitCount);
|
||||
|
||||
foreach (Transform rootObject in roots)
|
||||
{
|
||||
RenderSplash(rootObject);
|
||||
}
|
||||
|
||||
roots.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds Meshes that are part of the rootObject and blits the material on them
|
||||
/// </summary>
|
||||
private void RenderSplash(Transform rootObject)
|
||||
{
|
||||
List<MeshFilter> meshFilters = NonAlloc.GetMeshFiltersInChildren(rootObject);
|
||||
for (int i = 0; i < meshFilters.Count; i++)
|
||||
{
|
||||
int id = meshFilters[i].GetInstanceID();
|
||||
if (!NonAlloc._blits.ContainsKey(id)) { NonAlloc._blits[id] = CreateMeshBlit(meshFilters[i]); }
|
||||
NonAlloc._blits[id].Blit();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up a new mesh blit on the mesh filter for the water spray
|
||||
/// </summary>
|
||||
private MeshBlit CreateMeshBlit(MeshFilter meshFilter)
|
||||
{
|
||||
MeshBlit newBlit = meshFilter.gameObject.AddComponent<MeshBlit>();
|
||||
newBlit.material = _sprayStampMaterial;
|
||||
newBlit.renderTexture = new RenderTexture(512, 512, 0, RenderTextureFormat.RHalf);
|
||||
newBlit.BlitsPerSecond = 30;
|
||||
|
||||
if (meshFilter.TryGetComponent(out Renderer renderer))
|
||||
{
|
||||
renderer.GetPropertyBlock(NonAlloc.PropertyBlock);
|
||||
|
||||
NonAlloc.PropertyBlock.SetTexture(WET_MAP_PROPERTY, newBlit.renderTexture);
|
||||
if (_waterBumpOverride)
|
||||
{
|
||||
NonAlloc.PropertyBlock.SetTexture(WET_BUMPMAP_PROPERTY, _waterBumpOverride);
|
||||
}
|
||||
|
||||
renderer.SetPropertyBlock(NonAlloc.PropertyBlock);
|
||||
}
|
||||
|
||||
return newBlit;
|
||||
}
|
||||
|
||||
private Matrix4x4 CreateStampMatrix(Pose pose, float angle)
|
||||
{
|
||||
Matrix4x4 viewMatrix = Matrix4x4.TRS(pose.position, pose.rotation, Vector3.one).inverse;
|
||||
viewMatrix.m20 *= -1f;
|
||||
viewMatrix.m21 *= -1f;
|
||||
viewMatrix.m22 *= -1f;
|
||||
viewMatrix.m23 *= -1f;
|
||||
return GL.GetGPUProjectionMatrix(Matrix4x4.Perspective(angle, 1, 0, _maxDistance), true) * viewMatrix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans destroyed MeshBlits form the dictionary
|
||||
/// </summary>
|
||||
private void OnDestroy()
|
||||
{
|
||||
NonAlloc.CleanUpDestroyedBlits();
|
||||
}
|
||||
|
||||
public void BeginUse()
|
||||
{
|
||||
_dampedUseStrength = 0f;
|
||||
_lastUseTime = Time.realtimeSinceStartup;
|
||||
}
|
||||
|
||||
public void EndUse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public float ComputeUseStrength(float strength)
|
||||
{
|
||||
float delta = Time.realtimeSinceStartup - _lastUseTime;
|
||||
_lastUseTime = Time.realtimeSinceStartup;
|
||||
if (strength > _dampedUseStrength)
|
||||
{
|
||||
_dampedUseStrength = Mathf.Lerp(_dampedUseStrength, strength, _triggerSpeed * delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dampedUseStrength = strength;
|
||||
}
|
||||
float progress = _strengthCurve.Evaluate(_dampedUseStrength);
|
||||
UpdateTriggerProgress(progress);
|
||||
return progress;
|
||||
}
|
||||
|
||||
private void UpdateTriggerProgress(float progress)
|
||||
{
|
||||
UpdateTriggerRotation(progress);
|
||||
|
||||
if (progress >= _fireThresold && !_wasFired)
|
||||
{
|
||||
_wasFired = true;
|
||||
SprayWater();
|
||||
}
|
||||
else if (progress <= _releaseThresold)
|
||||
{
|
||||
_wasFired = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Allocation helpers
|
||||
/// </summary>
|
||||
static class NonAlloc
|
||||
{
|
||||
public static readonly Collider[] _overlapResults = new Collider[12];
|
||||
public static readonly Dictionary<int, MeshBlit> _blits = new Dictionary<int, MeshBlit>();
|
||||
public static MaterialPropertyBlock PropertyBlock => _block != null ? _block : _block = new MaterialPropertyBlock();
|
||||
|
||||
private static readonly List<MeshFilter> _meshFilters = new List<MeshFilter>();
|
||||
private static readonly HashSet<Transform> _roots = new HashSet<Transform>();
|
||||
private static MaterialPropertyBlock _block;
|
||||
|
||||
public static List<MeshFilter> GetMeshFiltersInChildren(Transform root)
|
||||
{
|
||||
root.GetComponentsInChildren(_meshFilters);
|
||||
return _meshFilters;
|
||||
}
|
||||
|
||||
public static HashSet<Transform> GetRootsFromOverlapResults(int hitCount)
|
||||
{
|
||||
_roots.Clear();
|
||||
for (int i = 0; i < hitCount; i++)
|
||||
{
|
||||
Transform root = GetRoot(_overlapResults[i]);
|
||||
_roots.Add(root);
|
||||
}
|
||||
return _roots;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the most likely 'root object' for the hit e.g. the rigidbody
|
||||
/// </summary>
|
||||
static Transform GetRoot(Collider hit)
|
||||
{
|
||||
return hit.attachedRigidbody ? hit.attachedRigidbody.transform :
|
||||
hit.transform.parent ? hit.transform.parent :
|
||||
hit.transform;
|
||||
}
|
||||
|
||||
public static void CleanUpDestroyedBlits()
|
||||
{
|
||||
if (!_blits.ContainsValue(null)) { return; }
|
||||
|
||||
foreach (int key in new List<int>(_blits.Keys))
|
||||
{
|
||||
if (_blits[key] == null) _blits.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00b3471f79f999345b21b7979abca356
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- sprayStampMaterial: {fileID: 2100000, guid: 44092c54cacca1046ac25e52c878a0c7, type: 2}
|
||||
- waterBumpOverride: {fileID: 2800000, guid: 06aafc7fcb186454893618a0b137089b, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,37 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: WaterSpray
|
||||
m_Shader: {fileID: 4800000, guid: 14c4f10921fa2ed46b4a9be3c07abeee, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _Stamp:
|
||||
m_Texture: {fileID: 2800000, guid: c6766195a787bd94cbe3f230af954ee4, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _StampMultipler: 5
|
||||
- _StampStrength: 3
|
||||
- _Subtract: 0.002
|
||||
- _UV: 1
|
||||
m_Colors:
|
||||
- _Subtract: {r: 0.039215688, g: 0.039215688, b: 0.039215688, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44092c54cacca1046ac25e52c878a0c7
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Oculus.Interaction.Demo
|
||||
{
|
||||
public class WaterSprayNozzleTransformer : MonoBehaviour, ITransformer
|
||||
{
|
||||
[SerializeField]
|
||||
private float _factor = 3f;
|
||||
[SerializeField]
|
||||
private float _snapAngle = 90;
|
||||
[SerializeField]
|
||||
[Range(0f, 1f)]
|
||||
private float _snappiness = 0.8f;
|
||||
[SerializeField]
|
||||
private int _maxSteps = 1;
|
||||
|
||||
private float _relativeAngle = 0f;
|
||||
private int _stepsCount = 0;
|
||||
private IGrabbable _grabbable;
|
||||
|
||||
private Pose _previousGrabPose;
|
||||
|
||||
public void Initialize(IGrabbable grabbable)
|
||||
{
|
||||
_grabbable = grabbable;
|
||||
}
|
||||
|
||||
public void BeginTransform()
|
||||
{
|
||||
_previousGrabPose = _grabbable.GrabPoints[0];
|
||||
_relativeAngle = 0.0f;
|
||||
_stepsCount = 0;
|
||||
}
|
||||
|
||||
public void UpdateTransform()
|
||||
{
|
||||
Pose grabPoint = _grabbable.GrabPoints[0];
|
||||
Transform targetTransform = _grabbable.Transform;
|
||||
Vector3 localAxis = Vector3.forward;
|
||||
Vector3 worldAxis = targetTransform.TransformDirection(localAxis);
|
||||
|
||||
Vector3 initialVector = Vector3.ProjectOnPlane(_previousGrabPose.right, worldAxis).normalized;
|
||||
Vector3 targetVector = Vector3.ProjectOnPlane(grabPoint.right, worldAxis).normalized;
|
||||
|
||||
float angleDelta = Vector3.SignedAngle(initialVector, targetVector, worldAxis) * _factor;
|
||||
|
||||
_relativeAngle += angleDelta;
|
||||
|
||||
if (Mathf.Abs(_relativeAngle) > _snapAngle * (1 - _snappiness)
|
||||
&& Mathf.Abs(_stepsCount + Mathf.Sign(_relativeAngle)) <= _maxSteps)
|
||||
{
|
||||
float currentAngle = targetTransform.localEulerAngles.z;
|
||||
int turns = Mathf.FloorToInt((currentAngle + _snappiness * 0.5f) / _snapAngle);
|
||||
float sign = Mathf.Sign(_relativeAngle);
|
||||
float angle = sign > 0 ? _snapAngle * (turns + 1) : _snapAngle * turns;
|
||||
Vector3 rot = targetTransform.localEulerAngles;
|
||||
rot.z = angle;
|
||||
targetTransform.localEulerAngles = rot;
|
||||
|
||||
_relativeAngle = 0;
|
||||
_stepsCount += (int)sign;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetTransform.Rotate(worldAxis, angleDelta, Space.World);
|
||||
}
|
||||
|
||||
_previousGrabPose = grabPoint;
|
||||
}
|
||||
|
||||
public void EndTransform() { }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1302feb954c92f43bb3d72f377721ee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user