squash commits
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
|
||||
#if Projected_Decals
|
||||
// List<RendererFragment>
|
||||
|
||||
// TODO: Calculate slot vertex offset in mesh, store in materialfragment
|
||||
// TODO: Generate DecalChunk at runtime. Pull the triangles that contain the
|
||||
// captured vertexes from the sample scene.
|
||||
// Make sure we can do this all at runtime.
|
||||
|
||||
public class Decal
|
||||
{
|
||||
private class RendererFragment
|
||||
{
|
||||
// public GeneratedMaterial generatedMaterial;
|
||||
public SkinnedMeshRenderer renderer;
|
||||
public List<DecalChunk> chunks;
|
||||
|
||||
public RendererFragment(SkinnedMeshRenderer ren)
|
||||
{
|
||||
renderer = ren;
|
||||
chunks = new List<DecalChunk>();
|
||||
}
|
||||
}
|
||||
|
||||
private class MaterialPacket
|
||||
{
|
||||
public MaterialFragment materialFragment;
|
||||
public GeneratedMaterial generatedMaterial;
|
||||
public MaterialPacket(GeneratedMaterial gMat, MaterialFragment mFrag)
|
||||
{
|
||||
materialFragment = mFrag;
|
||||
generatedMaterial = gMat;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string uniqueName;
|
||||
public List<DecalChunk> DecalChunks;
|
||||
public Material DecalMaterial; // Decal textures must be clamped.
|
||||
|
||||
private void ApplyChunks(RendererFragment renderFragment)
|
||||
{
|
||||
SkinnedMeshRenderer smr = renderFragment.renderer;
|
||||
|
||||
int MatIndex = -1;
|
||||
for (int i = 0; i < smr.materials.Length; i++)
|
||||
{
|
||||
Material m = smr.materials[i];
|
||||
if (m.name == uniqueName)
|
||||
{
|
||||
MatIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (MatIndex == -1)
|
||||
{
|
||||
Material newMaterial = new Material(DecalMaterial);
|
||||
newMaterial.name = uniqueName;
|
||||
List<Material> mats = new List<Material>();
|
||||
smr.GetMaterials(mats);
|
||||
mats.Add(newMaterial);
|
||||
MatIndex = mats.Count - 1;
|
||||
smr.sharedMesh.subMeshCount++;
|
||||
}
|
||||
|
||||
List<int> decalTris = new List<int>();
|
||||
|
||||
|
||||
|
||||
foreach(DecalChunk chunk in DecalChunks)
|
||||
{
|
||||
decalTris.AddRange(chunk.TriangleList);
|
||||
}
|
||||
|
||||
smr.sharedMesh.SetTriangles(decalTris, MatIndex);
|
||||
}
|
||||
|
||||
public void ApplySubmesh(UMAData uMAData)
|
||||
{
|
||||
Dictionary<string, MaterialPacket> SlotsToPacket = new Dictionary<string, MaterialPacket>();
|
||||
Dictionary<string, RendererFragment> RendererFragments = new Dictionary<string, RendererFragment>();
|
||||
|
||||
// todo: build a dictionary of the slots, and the material fragment.
|
||||
foreach(var mat in uMAData.generatedMaterials.materials)
|
||||
{
|
||||
foreach(var slotmat in mat.materialFragments)
|
||||
{
|
||||
SlotsToPacket.Add(slotmat.slotData.slotName,new MaterialPacket(mat,slotmat));
|
||||
}
|
||||
}
|
||||
|
||||
foreach(DecalChunk chunk in DecalChunks)
|
||||
{
|
||||
if (SlotsToPacket.ContainsKey(chunk.slotName))
|
||||
{
|
||||
var materialPacket = SlotsToPacket[chunk.slotName];
|
||||
chunk.fragment = materialPacket.materialFragment;
|
||||
string rendererName = materialPacket.generatedMaterial.skinnedMeshRenderer.name;
|
||||
if (!RendererFragments.ContainsKey(rendererName))
|
||||
{
|
||||
RendererFragments.Add(rendererName, new RendererFragment(materialPacket.generatedMaterial.skinnedMeshRenderer));
|
||||
}
|
||||
RendererFragments[rendererName].chunks.Add(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(RendererFragment rf in RendererFragments.Values)
|
||||
{
|
||||
ApplyChunks(rf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DecalChunk
|
||||
{
|
||||
public string slotName;
|
||||
|
||||
public int[] TriangleList;
|
||||
public MaterialFragment fragment;
|
||||
|
||||
// index of vertexes in the slot.
|
||||
// These need to be translate d to the mesh index after the build is complete.
|
||||
// To do this, we will need to track for each slot in the UMAData (during the build process)
|
||||
// What SMR the slot is actually in, in case there are multiples
|
||||
// what vertex position the slot starts at in the SMR
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: deba20c3855a436478ceaf5a0b2db7ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/Decal.cs
|
||||
uploadId: 679826
|
||||
@@ -0,0 +1,271 @@
|
||||
using System.Collections.Generic;
|
||||
using UMA;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public class DecalDefinition
|
||||
{
|
||||
public string Name;
|
||||
public int InitialIndex;
|
||||
public GameObject DecalMeshObject;
|
||||
public Mesh bakedMesh;
|
||||
public Plane[] planesInWorldSpace;
|
||||
public int VertexNumber;
|
||||
public Vector3 WorldImpactPoint;
|
||||
public Vector3 LocalImpactPoint;
|
||||
|
||||
public Material material;
|
||||
public float offset; // zbias or offset for rendering. vertex = vertex + normal * offset.
|
||||
|
||||
List<DecalInstance> Instances = new List<DecalInstance>();
|
||||
|
||||
public GameObject InstantiateSimpleDecal(GameObject umaParent, SkinnedMeshRenderer baseRenderer)
|
||||
{
|
||||
// instantiate a new one here???
|
||||
|
||||
GameObject newDecal = GameObject.Instantiate(DecalMeshObject,umaParent.transform);
|
||||
SkinnedMeshRenderer smr = newDecal.GetComponent<SkinnedMeshRenderer>();
|
||||
if (smr == null)
|
||||
{
|
||||
Debug.LogWarning("Unable to instantiate decal - no SMR");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Copy bindposes from main.
|
||||
// copy bones from main.
|
||||
smr.sharedMesh.bindposes = baseRenderer.sharedMesh.bindposes;
|
||||
smr.bones = baseRenderer.bones;
|
||||
|
||||
return newDecal;
|
||||
}
|
||||
|
||||
public void AddInstance(UMAData umaData, List<int> Vertexes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddSubmesh(SkinnedMeshRenderer smr)
|
||||
{
|
||||
// we can't reuse the vertexes because the UV coordinates are different...
|
||||
|
||||
if (Instances == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instances.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Material> mats = new List<Material>();
|
||||
smr.GetMaterials(mats);
|
||||
mats.Add(material);
|
||||
|
||||
// read old data
|
||||
List<Vector3> Vertexes = new List<Vector3>();
|
||||
List<Vector3> Normals = new List<Vector3>();
|
||||
List<Vector4> Tangents = new List<Vector4>();
|
||||
List<Color32> Colors = new List<Color32>();
|
||||
List<Vector2> UV = new List<Vector2>();
|
||||
List<Vector2> UV2 = new List<Vector2>();
|
||||
List<Vector2> UV3 = new List<Vector2>();
|
||||
List<Vector2> UV4 = new List<Vector2>();
|
||||
List<int> Tris = new List<int>();
|
||||
// TODO: these should be NativeArray. Size to mesh size + all DI sizes.
|
||||
List<byte> bonesPerVertex = new List<byte>();
|
||||
List<BoneWeight1> boneWeights = new List<BoneWeight1>();
|
||||
|
||||
Mesh mesh = smr.sharedMesh;
|
||||
|
||||
mesh.GetVertices(Vertexes);
|
||||
mesh.GetNormals(Normals);
|
||||
mesh.GetTangents(Tangents);
|
||||
mesh.GetColors(Colors);
|
||||
mesh.GetUVs(0, UV);
|
||||
mesh.GetUVs(1, UV2);
|
||||
mesh.GetUVs(2, UV3);
|
||||
mesh.GetUVs(3, UV4);
|
||||
bonesPerVertex.AddRange(mesh.GetBonesPerVertex());
|
||||
boneWeights.AddRange(mesh.GetAllBoneWeights());
|
||||
|
||||
// boneweights
|
||||
// bonespervertex
|
||||
// blendshapes <-- later?
|
||||
|
||||
int baseVertex = Vertexes.Count;
|
||||
|
||||
foreach(DecalInstance di in Instances)
|
||||
{
|
||||
Vertexes.AddRange(di.vertexes);
|
||||
|
||||
// add the triangles
|
||||
for(int i=0;i<di.TriangleList.Length;i++)
|
||||
{
|
||||
Tris.Add(di.TriangleList[i] + baseVertex);
|
||||
}
|
||||
// add the boneweights
|
||||
for(int i=0;i<di.boneWeights.Length;i++)
|
||||
{
|
||||
BoneWeight1 bw = di.boneWeights[i];
|
||||
bw.boneIndex += baseVertex;
|
||||
boneWeights.Add(bw);
|
||||
}
|
||||
bonesPerVertex.AddRange(di.bonesPerVertex);
|
||||
// go to next DecalInstance
|
||||
baseVertex += di.vertexes.Length;
|
||||
}
|
||||
|
||||
mesh.SetVertices(Vertexes);
|
||||
mesh.SetNormals(Normals);
|
||||
mesh.SetTangents(Tangents);
|
||||
mesh.SetColors(Colors);
|
||||
mesh.SetUVs(0, UV);
|
||||
mesh.SetUVs(1, UV2);
|
||||
mesh.SetUVs(2, UV3);
|
||||
mesh.SetUVs(3, UV4);
|
||||
|
||||
// Set the submesh
|
||||
mesh.subMeshCount++;
|
||||
int newSubmesh = mesh.subMeshCount - 1;
|
||||
mesh.SetIndices(Tris, MeshTopology.Triangles, newSubmesh);
|
||||
// todo: these should not use temp NativeArrays, but always be NativeArrays.
|
||||
var unityBonesPerVertex = new NativeArray<byte>(bonesPerVertex.ToArray(), Allocator.Persistent);
|
||||
var unityBoneWeights = new NativeArray<BoneWeight1>(boneWeights.ToArray(), Allocator.Persistent);
|
||||
mesh.SetBoneWeights(unityBonesPerVertex, unityBoneWeights);
|
||||
unityBonesPerVertex.Dispose();
|
||||
unityBoneWeights.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public struct faceData
|
||||
{
|
||||
int oldFaceNumber;
|
||||
Vector3 Normal;
|
||||
}
|
||||
|
||||
public class DecalInstance
|
||||
{
|
||||
float offset; // z bias, or add to vertexes?
|
||||
public Vector3[] vertexes; // copied from slot(s)
|
||||
public Vector3[] normals; // copied from slot(s)
|
||||
public Vector4[] tangents; // copied from slot(s)
|
||||
public Color32[] colors32; // copied from slot(s)
|
||||
public Vector2[] uv; // calculated at capture time by projecting to plane
|
||||
public int[] TriangleList; // calculated at capture time (each triangle found is translated to local triangles and added to list).
|
||||
public byte[] bonesPerVertex;
|
||||
public BoneWeight1[] boneWeights;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a skinned decal
|
||||
/// </summary>
|
||||
/// <param name="t">t is the transform of the meshes game object in the scene.</param>
|
||||
/// <param name="m">m is the mesh as it is *right now* in the scene, captured at the current frame.
|
||||
/// It's used in place of the meshdata, and is used for everything *except* as the vertex position
|
||||
/// when creating the skinned mesh!!!</param>
|
||||
/// <param name="RayOrigin">RayOrigin is the origin of the ray. Used to determine if a face is "facing" the origin of the decal.</param>
|
||||
/// <param name="meshData"> This is the UMAMeshData that holds all the data. This is the information
|
||||
/// that is pre-bound to the rig. It's used for constructing the submesh</param>
|
||||
/// <param name="planes">planes is the list of planes in world space that define the bounds</param>
|
||||
/// <returns></returns>
|
||||
public bool Create(Transform t, Mesh m, Vector3 RayOrigin, UMAMeshData meshData, Plane[] planes)
|
||||
{
|
||||
List<Vector3> newVerts = new List<Vector3>();
|
||||
List<Vector3> newNormals = new List<Vector3>();
|
||||
List<Vector4> newTangents = new List<Vector4>();
|
||||
List<Color32> newColors32 = new List<Color32>();
|
||||
List<Vector2> newUv = new List<Vector2>();
|
||||
List<int> newTriangleList = new List<int>();
|
||||
List<byte> newBonesPerVertex = new List<byte>();
|
||||
List<BoneWeight1> newBoneWeights = new List<BoneWeight1>();
|
||||
|
||||
List<int> oldVertexNumbers = new List<int>();
|
||||
HashSet<int> vertHash = new HashSet<int>();
|
||||
|
||||
// calculate the face normals for each vertex.
|
||||
// int = the source vertex number from the mesh.
|
||||
// List<Vector3> = the list of normals for this vertex (one from each face it's connected to).
|
||||
//Dictionary<int, List<faceData>> oldVertexnumberFaceNormals = CalculateFaceNormals(m, meshData);
|
||||
|
||||
List<Vector3> meshVerts = new List<Vector3>();
|
||||
m.GetVertices(meshVerts);
|
||||
|
||||
for (int i=0;i<m.vertexCount;i++)
|
||||
{
|
||||
// this vertex is in world space.
|
||||
Vector3 vert = t.TransformPoint(meshVerts[i]);
|
||||
if (OnRight(vert,planes))
|
||||
{
|
||||
oldVertexNumbers.Add(i);
|
||||
vertHash.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
// now look through every face that has the vertexes in it.
|
||||
// if the face is facing the origin, then add it.
|
||||
Plane p = new Plane();
|
||||
for(int i=0;i<m.subMeshCount;i++)
|
||||
{
|
||||
var smd = m.GetSubMesh(i);
|
||||
|
||||
// UMA only creates triangle lists, so if this fails, then something has changed...
|
||||
if (smd.topology == MeshTopology.Triangles)
|
||||
{
|
||||
int[] submeshtris = m.GetIndices(i);
|
||||
for (int v=0;v<smd.indexCount;v+= 3)
|
||||
{
|
||||
int i1 = submeshtris[v];
|
||||
int i2 = submeshtris[v + 1];
|
||||
int i3 = submeshtris[v + 2];
|
||||
|
||||
p.Set3Points(meshVerts[i1], meshVerts[i2], meshVerts[i3]);
|
||||
// Does the triangle face the origin?
|
||||
if (p.GetDistanceToPoint(RayOrigin) >= 0.0f)
|
||||
{
|
||||
if (vertHash.Contains(i1) || vertHash.Contains(i2) || vertHash.Contains(i3))
|
||||
{
|
||||
// Add this triangle.
|
||||
// add meshVerts[i1], meshVerts[i2], meshVerts[i3] to new triangle list.
|
||||
// add translation for i1,i2,i3 to lookup (new, old)
|
||||
// Calculate UV for each one based on distance to UV planes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if vertex is inside plane group.
|
||||
private bool OnRight(Vector3 vert, Plane[] planes)
|
||||
{
|
||||
foreach (Plane p in planes)
|
||||
{
|
||||
if (p.GetDistanceToPoint(vert) <= 0.0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private Dictionary<int, List<faceData>> CalculateFaceNormals(Mesh m, UMAMeshData meshData)
|
||||
{
|
||||
Dictionary<int, List<faceData>> retval = new Dictionary<int, List<faceData>>();
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// index of vertexes in the slot.
|
||||
// These need to be translate d to the mesh index after the build is complete.
|
||||
// To do this, we will need to track for each slot in the UMAData (during the build process)
|
||||
// What SMR the slot is actually in, in case there are multiples
|
||||
// what vertex position the slot starts at in the SMR
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5960693ae28da44993cd40ca719a2a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/DecalDefinition.cs
|
||||
uploadId: 679826
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class DecalIndicator : MonoBehaviour
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
public Ray Ray;
|
||||
public Vector3 LocalEuler;
|
||||
public GameObject visualPlane;
|
||||
public GameObject visualCube;
|
||||
|
||||
public Plane UVPlane;
|
||||
public GameObject U1;
|
||||
public GameObject U2;
|
||||
public GameObject V1;
|
||||
public GameObject V2;
|
||||
public GameObject Front;
|
||||
public GameObject Back;
|
||||
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
UVPlane = CalculatePlane(visualPlane);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Plane CalculatePlane(GameObject go)
|
||||
{
|
||||
MeshFilter mf = go.GetComponent<MeshFilter>();
|
||||
if (mf != null)
|
||||
{
|
||||
int vertcount = mf.sharedMesh.vertexCount;
|
||||
int size = Convert.ToInt32(Mathf.Sqrt(vertcount));
|
||||
|
||||
Vector3 v1 = mf.sharedMesh.vertices[0];
|
||||
Vector3 v2 = mf.sharedMesh.vertices[1];
|
||||
Vector3 v3 = mf.sharedMesh.vertices[size + 1];
|
||||
|
||||
v1 = gameObject.transform.localToWorldMatrix * v1;
|
||||
v2 = gameObject.transform.localToWorldMatrix * v2;
|
||||
v3 = gameObject.transform.localToWorldMatrix * v3;
|
||||
|
||||
Plane p = new Plane(v1, v2, v3);
|
||||
return p;
|
||||
}
|
||||
throw new Exception("Unable to calc plane.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59b2ea4fb624d594ca0b363db59b1b15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/DecalIndicator.cs
|
||||
uploadId: 679826
|
||||
@@ -0,0 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class DecalManager : MonoBehaviour
|
||||
{
|
||||
public List<DecalDefinition> Decals = new List<DecalDefinition>();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4aedd86eec0d63a408d954c29100a02d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/DecalManager.cs
|
||||
uploadId: 679826
|
||||
Binary file not shown.
@@ -0,0 +1,135 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 170273e2f246de342a674afcef7c9b34
|
||||
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: 1
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.0293
|
||||
normalMapFilter: 1
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
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
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
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: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/DecalNormal.psd
|
||||
uploadId: 679826
|
||||
@@ -0,0 +1,139 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-2356353477197238579
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 9
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: DemoDecal
|
||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- _NORMALMAP
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
m_Texture: {fileID: 2800000, guid: dbbeae2754888b04080fa3e6711086fe, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 2800000, guid: 170273e2f246de342a674afcef7c9b34, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _ClearCoatMask: 0
|
||||
- _ClearCoatSmoothness: 0
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DetailAlbedoMapScale: 1
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _EnvironmentReflections: 1
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 1
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _Smoothness: 0
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _UVSec: 0
|
||||
- _WorkflowMode: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f456e456d024652418f3bbb8411f239c
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/DemoDecal.mat
|
||||
uploadId: 679826
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
@@ -0,0 +1,135 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbbeae2754888b04080fa3e6711086fe
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 8
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
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: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
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:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/DemoDecal.png
|
||||
uploadId: 679826
|
||||
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UMA
|
||||
{
|
||||
public interface IUMAEventHookup
|
||||
{
|
||||
void HookupEvents(SlotDataAsset slot);
|
||||
void Begun(UMAData umaData);
|
||||
void Completed(UMAData umaData,GameObject slotObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28db8065707fe9e448781ae42c713219
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/IUMAEventHookup.cs
|
||||
uploadId: 679826
|
||||
@@ -0,0 +1,642 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using UnityEngine.SceneManagement;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UMA
|
||||
{
|
||||
public class SimpleDecal : MonoBehaviour, IUMAEventHookup
|
||||
{
|
||||
// These need to be set by the editor.
|
||||
// ****************************************************************************
|
||||
public int[] boneHashes; // hash of bone names
|
||||
public string[] boneNames; // the names of the bones.
|
||||
public byte[] bonesPerVertex; // 1 per vertex
|
||||
public BoneWeight1[] capturedBoneWeights; // weight / boneIndex
|
||||
// ****************************************************************************
|
||||
public BoneWeight1[] finalBoneWeights = new BoneWeight1[0]; // weight / boneIndex
|
||||
private Dictionary<int, int> NameToBone = new Dictionary<int, int>();
|
||||
Vector3[] translated = new Vector3[0];
|
||||
public UMAMeshData meshData;
|
||||
public Vector3 Offset = Vector3.zero;
|
||||
public Vector3 Rotation = Vector3.zero;
|
||||
// public Quaternion Orientation = Quaternion.identity;
|
||||
|
||||
// temp
|
||||
private GameObject vmarker;
|
||||
private GameObject sceneRoot;
|
||||
private Scene editorScene;
|
||||
private Vector3 InitialSpot;
|
||||
|
||||
|
||||
public void Configure(string[] _boneNames, int[] _boneHashes, byte[] _bonesPerVertex, BoneWeight1[] _boneWeights)
|
||||
{
|
||||
// this
|
||||
boneHashes = _boneHashes;
|
||||
boneNames = _boneNames;
|
||||
capturedBoneWeights = _boneWeights;
|
||||
bonesPerVertex = _bonesPerVertex;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public void SaveDecal(string Name, string newAssetPath, bool addToLibrary, SkinnedMeshRenderer smr, DecalDefinition decal,GameObject marker1, Scene editScene,GameObject Root)
|
||||
{
|
||||
if (newAssetPath.StartsWith(Application.dataPath))
|
||||
{
|
||||
newAssetPath = "Assets"+ newAssetPath.Substring(Application.dataPath.Length);
|
||||
}
|
||||
|
||||
string meshPath = Path.Combine(newAssetPath, Name + "_Mesh.asset");
|
||||
string prefabPath = Path.Combine(newAssetPath, Name+".prefab");
|
||||
string slotPath = Path.Combine(newAssetPath, Name + ".asset");
|
||||
|
||||
/*
|
||||
MeshFilter mf = decal.GetComponent<MeshFilter>();
|
||||
AssetDatabase.CreateAsset(mf.mesh, meshPath );
|
||||
AssetDatabase.SaveAssets();
|
||||
*/
|
||||
|
||||
InitialSpot = decal.WorldImpactPoint;
|
||||
vmarker = marker1;
|
||||
editScene = editorScene;
|
||||
sceneRoot = Root;
|
||||
|
||||
meshData = new UMAMeshData();
|
||||
#if USE_TestMesh
|
||||
MeshFilter mf = this.gameObject.GetComponent<MeshFilter>();
|
||||
meshData.RetrieveDataFromUnityMesh(mf.sharedMesh);
|
||||
|
||||
// local to world (object)
|
||||
// world to local (root)
|
||||
Matrix4x4 mat = new Matrix4x4();
|
||||
Transform root = smr.rootBone;
|
||||
if (root == null)
|
||||
{
|
||||
foreach(Transform t in smr.transform.parent)
|
||||
{
|
||||
if (t.name.ToLower() == "root")
|
||||
{
|
||||
root = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (root == null)
|
||||
{
|
||||
foreach (Transform t in smr.transform.parent)
|
||||
{
|
||||
if (t.gameObject.GetComponent<SkinnedMeshRenderer>() == null)
|
||||
{
|
||||
// Maybe it's this one?
|
||||
if (t.childCount > 0)
|
||||
{
|
||||
root = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (root == null)
|
||||
{
|
||||
mat.SetTRS(Vector3.zero, Quaternion.identity, Vector3.one);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.SetTRS(Vector3.zero, root.localRotation, Vector3.one);
|
||||
}
|
||||
/*
|
||||
for(int i=0;i<meshData.vertices.Length;i++)
|
||||
{
|
||||
meshData.vertices[i] = mat.inverse * meshData.vertices[i];
|
||||
}
|
||||
*/
|
||||
|
||||
meshData.UpdateBones(smr.rootBone, smr.bones);
|
||||
meshData.ManagedBoneWeights = this.finalBoneWeights; // Not right
|
||||
meshData.ManagedBonesPerVertex = this.bonesPerVertex;
|
||||
meshData.bindPoses = smr.sharedMesh.bindposes;
|
||||
meshData.SlotName = "Decal";
|
||||
meshData.clothSkinningSerialized = new Vector2[0];
|
||||
#else
|
||||
// get all the triangles inside the radius that face the ray.
|
||||
|
||||
meshData.subMeshCount = 1;
|
||||
meshData.submeshes = new SubMeshTriangles[1];
|
||||
meshData.submeshes[0].SetTriangles(AccumulateTriangles(decal.bakedMesh,decal.planesInWorldSpace,smr,decal.WorldImpactPoint));
|
||||
meshData.vertices = smr.sharedMesh.vertices;
|
||||
meshData.normals = smr.sharedMesh.normals;
|
||||
meshData.uv = new Vector2[smr.sharedMesh.vertices.Length];
|
||||
meshData.uv2 = smr.sharedMesh.uv2;
|
||||
meshData.uv3 = smr.sharedMesh.uv3;
|
||||
meshData.uv4 = smr.sharedMesh.uv4;
|
||||
meshData.colors32 = smr.sharedMesh.colors32;
|
||||
meshData.vertexCount = meshData.vertices.Length;
|
||||
meshData.tangents = smr.sharedMesh.tangents;
|
||||
|
||||
meshData.bindPoses = smr.sharedMesh.bindposes;
|
||||
meshData.ManagedBoneWeights = smr.sharedMesh.GetAllBoneWeights().ToArray();
|
||||
meshData.ManagedBonesPerVertex = smr.sharedMesh.GetBonesPerVertex().ToArray();
|
||||
meshData.SlotName = "Decal";
|
||||
meshData.clothSkinningSerialized = new Vector2[0];
|
||||
|
||||
ProjectUV(meshData, decal.bakedMesh, decal.planesInWorldSpace,smr);
|
||||
|
||||
#endif
|
||||
gameObject.name = Name;
|
||||
GameObject prefab = PrefabUtility.SaveAsPrefabAsset(this.gameObject, prefabPath);
|
||||
SlotDataAsset sda = CustomAssetUtility.CreateAsset<SlotDataAsset>(slotPath, false, Name);
|
||||
sda.slotName = Name;
|
||||
sda.SlotObject = prefab;
|
||||
|
||||
/*
|
||||
mf = prefab.GetComponent<MeshFilter>();
|
||||
mf.mesh = AssetDatabase.LoadAssetAtPath<Mesh>(meshPath);
|
||||
SkinnedMeshRenderer smr = prefab.GetComponent<SkinnedMeshRenderer>();
|
||||
smr.sharedMesh = mf.mesh;
|
||||
*/
|
||||
|
||||
|
||||
EditorUtility.SetDirty(sda);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
if (addToLibrary)
|
||||
{
|
||||
UMAAssetIndexer.Instance.AddAsset(typeof(SlotDataAsset),Name, slotPath, sda);
|
||||
EditorUtility.DisplayDialog("UMA", "Decal Created and added to library", "OK");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("UMA", "Decal Created. Don't forget to add it to the library", "OK");
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 GetUV(Plane[] planesinWS,Vector3 vertinWS)
|
||||
{
|
||||
Plane u0 = planesinWS[0];
|
||||
Plane u1 = planesinWS[1];
|
||||
Plane v0 = planesinWS[2];
|
||||
Plane v1 = planesinWS[3];
|
||||
|
||||
float ud0 = u0.GetDistanceToPoint(vertinWS);
|
||||
float ud1 = u1.GetDistanceToPoint(vertinWS);
|
||||
float vd0 = v0.GetDistanceToPoint(vertinWS);
|
||||
float vd1 = v1.GetDistanceToPoint(vertinWS);
|
||||
|
||||
float U_One = Mathf.Abs((u0.ClosestPointOnPlane(vertinWS) - u1.ClosestPointOnPlane(vertinWS)).magnitude);
|
||||
float V_One = Mathf.Abs((v0.ClosestPointOnPlane(vertinWS) - v1.ClosestPointOnPlane(vertinWS)).magnitude);
|
||||
|
||||
return new Vector2(ud0 / U_One, vd0 / V_One);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// planes needs to be in worldspace!!!!!
|
||||
/// </summary>
|
||||
/// <param name="meshData"></param>
|
||||
/// <param name="bakedMesh"></param>
|
||||
/// <param name="planes"></param>
|
||||
/// <param name="smr"></param>
|
||||
private void ProjectUV(UMAMeshData meshData, Mesh bakedMesh, Plane[] planes, SkinnedMeshRenderer smr)
|
||||
{
|
||||
Matrix4x4 mat = smr.gameObject.transform.localToWorldMatrix;
|
||||
NativeArray<int> tris = meshData.submeshes[0].GetTriangles();
|
||||
|
||||
for (int tri = 0; tri < tris.Length; tri+=3)
|
||||
{
|
||||
int v0index = tris[tri];
|
||||
int v1index = tris[tri+1];
|
||||
int v2index = tris[tri+2];
|
||||
|
||||
Vector3 v0 = mat * meshData.vertices[v0index];
|
||||
Vector3 v1 = mat * meshData.vertices[v1index];
|
||||
Vector3 v2 = mat * meshData.vertices[v2index];
|
||||
|
||||
Vector2 uv0 = GetUV(planes, v0);
|
||||
Vector2 uv1 = GetUV(planes, v1);
|
||||
Vector2 uv2 = GetUV(planes, v2);
|
||||
|
||||
meshData.uv[v0index] = uv0;
|
||||
meshData.uv[v1index] = uv1;
|
||||
meshData.uv[v2index] = uv2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool PlanesContains(Plane[] planes,Vector3 vert)
|
||||
{
|
||||
foreach(Plane p in planes)
|
||||
{
|
||||
float dist = p.GetDistanceToPoint(vert);
|
||||
if (dist < 0.0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int[] AccumulateTriangles(Mesh bakedMesh, Plane[] planes, SkinnedMeshRenderer smr,Vector3 worldPoint)
|
||||
{
|
||||
//List<int> insideVertexes = new List<int>();
|
||||
HashSet<int> insideVertexes = new HashSet<int>();
|
||||
List<int> newTriangles = new List<int>();
|
||||
/* Vector3 VertMax = new Vector3();
|
||||
|
||||
for(int i=0;i<bakedMesh.vertices.Length;i++)
|
||||
{
|
||||
|
||||
Vector3 vert = smr.gameObject.transform.TransformPoint(bakedMesh.vertices[i]);
|
||||
|
||||
if (vert.y > VertMax.y)
|
||||
{
|
||||
VertMax = vert;
|
||||
}
|
||||
|
||||
if (PlanesContains(planes,vert))
|
||||
{
|
||||
insideVertexes.Add(i);
|
||||
}
|
||||
}
|
||||
GameObject.Instantiate(vmarker, VertMax, Quaternion.identity,sceneRoot.transform); */
|
||||
|
||||
for (int i=0;i<bakedMesh.subMeshCount;i++)
|
||||
{
|
||||
int[] triangles = bakedMesh.GetTriangles(i);
|
||||
for (int tri = 0; tri < triangles.Length; tri += 3)
|
||||
{
|
||||
bool isAffected = false;
|
||||
|
||||
|
||||
|
||||
if (TriangleIntersects(tri, triangles, bakedMesh, smr, planes, worldPoint))
|
||||
{
|
||||
isAffected = true;
|
||||
}
|
||||
|
||||
//if (insideVertexes.Contains(triangles[tri])) isAffected = true;
|
||||
//if (insideVertexes.Contains(triangles[tri+1])) isAffected = true;
|
||||
//if (insideVertexes.Contains(triangles[tri+2])) isAffected = true;
|
||||
|
||||
// if any indexes are inside the space,
|
||||
// then we need that triangle.
|
||||
if (isAffected)
|
||||
{
|
||||
newTriangles.Add(triangles[tri]);
|
||||
newTriangles.Add(triangles[tri+1]);
|
||||
newTriangles.Add(triangles[tri+2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newTriangles.ToArray();
|
||||
}
|
||||
|
||||
private bool TriangleIntersects(int tri, int[] triangles, Mesh bakedMesh, SkinnedMeshRenderer smr,Plane[] planes, Vector3 worldPoint)
|
||||
{
|
||||
// if all vertexes are on outside U1 or U2
|
||||
// if all vertexes are on outside V1 or V2
|
||||
// return false
|
||||
//
|
||||
// else return true.
|
||||
|
||||
Transform transform = smr.gameObject.transform;
|
||||
|
||||
int backu1count = 0;
|
||||
int backu2count = 0;
|
||||
int backv1count = 0;
|
||||
int backv2count = 0;
|
||||
int backf1count = 0;
|
||||
int backb1count = 0;
|
||||
|
||||
Plane u1 = planes[0];
|
||||
Plane u2 = planes[1];
|
||||
Plane v1 = planes[2];
|
||||
Plane v2 = planes[3];
|
||||
Plane f1 = planes[4];
|
||||
Plane b1 = planes[5];
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<3;i++)
|
||||
{
|
||||
int vertexnum = triangles[tri + i];
|
||||
Vector3 worldvert = transform.TransformPoint(bakedMesh.vertices[vertexnum]);
|
||||
float u1dist = u1.GetDistanceToPoint(worldvert);
|
||||
float u2dist = u2.GetDistanceToPoint(worldvert);
|
||||
float v1dist = v1.GetDistanceToPoint(worldvert);
|
||||
float v2dist = v2.GetDistanceToPoint(worldvert);
|
||||
float f1dist = f1.GetDistanceToPoint(worldvert);
|
||||
float b1dist = b1.GetDistanceToPoint(worldvert);
|
||||
|
||||
|
||||
if (u1dist < 0)
|
||||
{
|
||||
backu1count++;
|
||||
}
|
||||
|
||||
if (u2dist < 0)
|
||||
{
|
||||
backu2count++;
|
||||
}
|
||||
|
||||
if (v1dist < 0)
|
||||
{
|
||||
backv1count++;
|
||||
}
|
||||
|
||||
if (v2dist < 0)
|
||||
{
|
||||
backv2count++;
|
||||
}
|
||||
|
||||
if (f1dist < 0)
|
||||
{
|
||||
backf1count++;
|
||||
}
|
||||
|
||||
if (b1dist < 0)
|
||||
{
|
||||
backb1count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Calculate plane from verts.
|
||||
// if ALL vertexes are "too far", then do not include
|
||||
|
||||
if (backu1count == 3 || backu2count == 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (backv1count == 3 || backv2count == 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (backb1count == 3 || backf1count == 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the triangle in world space
|
||||
Vector3 t1 = transform.TransformPoint(bakedMesh.vertices[triangles[tri]]);
|
||||
Vector3 t2 = transform.TransformPoint(bakedMesh.vertices[triangles[tri+1]]);
|
||||
Vector3 t3 = transform.TransformPoint(bakedMesh.vertices[triangles[tri+2]]);
|
||||
|
||||
// if it faces away, don't make a decal
|
||||
Plane TriWorldPlane = new Plane(t1, t2, t3);
|
||||
if (TriWorldPlane.GetDistanceToPoint(worldPoint) < 0.0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// in the volume.
|
||||
// faces the indicator.
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#region runtime
|
||||
public void UpdateBones(UMAData umaData)
|
||||
{
|
||||
Dictionary<int, int> HashToPosition = new Dictionary<int, int>();
|
||||
|
||||
SkinnedMeshRenderer renderer = umaData.GetRenderer(0);
|
||||
|
||||
// No new bones added
|
||||
if (boneHashes.Length == renderer.bones.Length)
|
||||
{
|
||||
finalBoneWeights = new BoneWeight1[0];
|
||||
return;
|
||||
}
|
||||
|
||||
// build translation table if needed
|
||||
// if (NameToBone.Count != renderer.bones.Length)
|
||||
// {
|
||||
NameToBone.Clear();
|
||||
for (int i = 0; i < renderer.bones.Length; i++)
|
||||
{
|
||||
Transform t = renderer.bones[i];
|
||||
NameToBone.Add(UMAUtils.StringToHash(t.name), i);
|
||||
}
|
||||
// }
|
||||
|
||||
// new bones added... need to translate
|
||||
finalBoneWeights = new BoneWeight1[capturedBoneWeights.Length];
|
||||
for (int i = 0; i < capturedBoneWeights.Length; i++)
|
||||
{
|
||||
BoneWeight1 oldbw = capturedBoneWeights[i];
|
||||
int Hash = capturedBoneWeights[i].boneIndex;
|
||||
|
||||
if (umaData.skeleton.boneHashData.ContainsKey(Hash))
|
||||
{
|
||||
var boneData = umaData.skeleton.boneHashData[Hash];
|
||||
|
||||
if (NameToBone.ContainsKey(boneData.boneNameHash))
|
||||
{
|
||||
finalBoneWeights[i].boneIndex = NameToBone[boneData.boneNameHash];
|
||||
finalBoneWeights[i].weight = capturedBoneWeights[i].weight;
|
||||
//Debug.Log($"UMA Bone Found with hash {boneData.boneNameHash} name {boneData.boneTransform.name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"UMA Bone not found with hash {boneData.boneNameHash} name {boneData.boneTransform.name}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Decal bone not found with hash {Hash}");
|
||||
}
|
||||
|
||||
/*
|
||||
int Hash = boneHashes[boneWeights[i].boneIndex];
|
||||
int Hash = capturedBoneWeights[i].boneIndex;
|
||||
if (umaData.skeleton.boneHashData.ContainsKey(Hash))
|
||||
{
|
||||
var boneData = umaData.skeleton.boneHashData[Hash];
|
||||
|
||||
if (NameToBone.ContainsKey(boneData.boneNameHash))
|
||||
{
|
||||
finalBoneWeights[i].boneIndex = NameToBone[boneData.boneNameHash];
|
||||
finalBoneWeights[i].weight = capturedBoneWeights[i].weight;
|
||||
Debug.Log($"UMA Bone Found with hash {boneData.boneNameHash} name {boneData.boneTransform.name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"UMA Bone not found with hash {boneData.boneNameHash} name {boneData.boneTransform.name}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Decal bone not found with hash {Hash}");
|
||||
} */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public bool invert;
|
||||
public bool root;
|
||||
public bool global;
|
||||
public bool position;
|
||||
|
||||
Matrix4x4 GetBoneTransform(UMAData umaData)
|
||||
{
|
||||
Matrix4x4 mat = Matrix4x4.identity;
|
||||
Quaternion rot = Quaternion.Euler(Rotation);
|
||||
mat.SetTRS(Offset, rot, Vector3.one);
|
||||
if (position)
|
||||
{
|
||||
Transform pos = umaData.skeleton.GetBoneTransform(UMAUtils.StringToHash("Position"));
|
||||
if (pos != null)
|
||||
{
|
||||
Matrix4x4 posMat = new Matrix4x4();
|
||||
posMat.SetTRS(pos.localPosition, Quaternion.identity /*pos.localRotation*/, Vector3.one);
|
||||
if (invert)
|
||||
{
|
||||
posMat = posMat.inverse;
|
||||
}
|
||||
|
||||
mat = mat * posMat;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Position bone not found?");
|
||||
}
|
||||
}
|
||||
if (global)
|
||||
{
|
||||
Transform global = umaData.skeleton.GetBoneTransform(UMAUtils.StringToHash("Global"));
|
||||
if (global != null)
|
||||
{
|
||||
Matrix4x4 globalMat = new Matrix4x4();
|
||||
globalMat.SetTRS(global.localPosition, Quaternion.identity/*global.localRotation*/, Vector3.one);
|
||||
if (invert)
|
||||
{
|
||||
globalMat = globalMat.inverse;
|
||||
}
|
||||
|
||||
mat = mat * globalMat;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Global bone not found?");
|
||||
}
|
||||
}
|
||||
|
||||
if (root)
|
||||
{
|
||||
Transform root = umaData.umaRoot.transform;
|
||||
if (root != null)
|
||||
{
|
||||
Matrix4x4 rootmat = new Matrix4x4();
|
||||
rootmat.SetTRS(Vector3.zero, root.localRotation, Vector3.one);
|
||||
if (invert)
|
||||
{
|
||||
rootmat = rootmat.inverse;
|
||||
}
|
||||
|
||||
mat = mat * rootmat;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Root bone not found?");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
Vector3[] TranslateVertices(Vector3[] verts, UMAData umaData)
|
||||
{
|
||||
Vector3[] tverts = new Vector3[verts.Length];
|
||||
Matrix4x4 mat = GetBoneTransform(umaData);
|
||||
|
||||
for(int i=0;i<verts.Length;i++)
|
||||
{
|
||||
tverts[i] = mat * (verts[i]+Offset);
|
||||
}
|
||||
|
||||
return tverts;
|
||||
}
|
||||
|
||||
private void ApplyToMesh(Mesh mesh,UMAData umaData)
|
||||
{
|
||||
mesh.subMeshCount = 1;
|
||||
mesh.triangles = new int[0];
|
||||
mesh.vertices = TranslateVertices(meshData.vertices,umaData);
|
||||
mesh.normals = meshData.normals;
|
||||
mesh.tangents = meshData.tangents;
|
||||
mesh.uv = meshData.uv;
|
||||
mesh.uv2 = meshData.uv2;
|
||||
mesh.uv3 = meshData.uv3;
|
||||
mesh.uv4 = meshData.uv4;
|
||||
mesh.colors32 = meshData.colors32;
|
||||
mesh.bindposes = meshData.bindPoses;
|
||||
|
||||
var subMeshCount = meshData.submeshes.Length;
|
||||
mesh.subMeshCount = subMeshCount;
|
||||
for (int i = 0; i < subMeshCount; i++)
|
||||
{
|
||||
mesh.SetIndices(meshData.submeshes[i].GetTriangles(), MeshTopology.Triangles, i);
|
||||
}
|
||||
mesh.RecalculateBounds();
|
||||
}
|
||||
|
||||
|
||||
public GameObject ApplyTo(UMAData umaData, SkinnedMeshRenderer baseRenderer,GameObject slotObject)
|
||||
{
|
||||
// instantiate a new one here???
|
||||
GameObject newDecal = GameObject.Instantiate(slotObject, umaData.transform);
|
||||
SkinnedMeshRenderer smr = newDecal.GetComponent<SkinnedMeshRenderer>();
|
||||
if (smr == null)
|
||||
{
|
||||
Debug.LogWarning("Unable to instantiate decal - no SMR");
|
||||
return null;
|
||||
}
|
||||
|
||||
Mesh m = new Mesh();
|
||||
ApplyToMesh(m,umaData);
|
||||
|
||||
// Copy bindposes from main.
|
||||
// copy bones from main.
|
||||
smr.sharedMesh = m;
|
||||
smr.sharedMesh.bindposes = baseRenderer.sharedMesh.bindposes;
|
||||
smr.bones = baseRenderer.bones;
|
||||
smr.sharedMesh = m;
|
||||
smr.rootBone = baseRenderer.rootBone;
|
||||
|
||||
/* OLD BANDAGE WAY
|
||||
NativeArray<byte> bpv = new NativeArray<byte>(bonesPerVertex, Allocator.Temp);
|
||||
NativeArray<BoneWeight1> bweights;
|
||||
bweights = new NativeArray<BoneWeight1>(finalBoneWeights, Allocator.Temp);
|
||||
|
||||
smr.sharedMesh.SetBoneWeights(bpv, bweights); */
|
||||
smr.gameObject.SetActive(false);
|
||||
smr.gameObject.SetActive(true);
|
||||
|
||||
return newDecal;
|
||||
}
|
||||
|
||||
public void Begun(UMAData umaData)
|
||||
{
|
||||
}
|
||||
|
||||
public void Completed(UMAData umaData,GameObject slotObject)
|
||||
{
|
||||
UpdateBones(umaData);
|
||||
ApplyTo(umaData, umaData.GetRenderer(0), slotObject);
|
||||
}
|
||||
|
||||
public void HookupEvents(SlotDataAsset slot)
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d32db59f6e6157442938b43899c62390
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 35611
|
||||
packageName: UMA 2
|
||||
packageVersion: 2.13
|
||||
assetPath: Assets/UMA/Core/Decals/Scripts/SimpleDecal.cs
|
||||
uploadId: 679826
|
||||
Reference in New Issue
Block a user