Main Page

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Added note about new syntax highlighting tag)
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Introduction ==
+
{| style="width: 100%;" cellspacing="5" cellpadding="0"
 +
| colspan="3" | <div style="width: 60%; margin: auto; background: #FFFFF; border: 1px solid #131313"><div style="background: #C8C4BD; border: 1px solid #131313; padding: 5px; margin: 3px; font-weight: bold; text-align: center;">Welcome to the UnifyWiki<br />The UnifyWiki is part of the [http://unifycommunity.com Unify Community] and is a place to find and share [http://unity3d.com/ Unity] knowledge. <br /></div></div>
  
This c# code demonstrates how to deformate a mesh at runtime using smoothing algorithms.
 
  
To solve this problem in a reasonable computational time a good algorithm is needed to
 
solve the adjacent vertex problem.  Unity lacks mesh manipulation utilities and some manual
 
effort is required to achieve this. 
 
  
(Note: I'm no unity expert so please don't shoot the piano player he is trying his best and improve anything.)
+
|-
  
== Basic Theory ==
+
{| style="width: 100%; margin: auto; text-align: center; border: none;"
 +
| [[File:Splash.jpg|link=Main_Page]]
 +
|}
  
Given a Mesh/SkinnedMeshRenderer  Vector3[] v = mesh.vertices,  and int[] t = mesh.triangles.
+
{| style="width: 100%;" cellspacing="5" cellpadding="0"
  
For each vertex i in the mesh, find the set of neighboring vertices.
+
| colspan="2" style="background: #FFFFFF; border: 1px solid #AAA; vertical-align: top;" |
 +
<div style="background: #787878; border: 1px solid #131313; padding: 5px; margin: 3px; font-weight: bold; text-align: center; font-size: 120%;">Wiki News</div>
  
Computing the Laplacian Smooth Filter p[i] = ( 1 / number of adjacent vertices ) * summation of the adjacent vertices.  
+
<div style="padding-left: 1em;">
 +
* <span style="color: #F00;">'''IMPORTANT:'''</span> syntax highlighting now uses different tags.  Where you previously could write '''<nowiki><csharp>, <javascript></nowiki>''' or '''<nowiki><boo></nowiki>''', you now have to write '''<nowiki><syntaxhighlight lang="csharp"></nowiki>'''.  The names used for each language have not changed.  You can learn more about the syntax highlighter's features [http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi here].
  
Laplacian smoothing introduces shrinkage, so the HC-Algorithm is applied as an extension to reduce this issue. (More computationally expensive though !).
+
* The spam filter has been tightened a bit.  If the wiki refuses an edit because it says it's spam and you don't know why, please contact an administrator.
  
== General Discussion ==
+
* It is possible to upload '''zip''' archives to the Unify wiki.  We encourage you to provide a zipped copy of your script or shader when adding a new article, as this will help to avoid problems with various web browsers where garbage characters are introduced into text which is copied and pasted from these pages.
  
Although the code demonstrates smoothing meshes, it provides a more generic strategy for manipulating meshes in Unity as many
+
* The maximum file size for any uploaded file is now '''512KB''', and this includes images as well as zip filesUnfortunately, '''unityPackage''' files are not directly supported at present, as we have been unable to make MediaWiki recognise the unusually long filename extension.  If you wish to add a unityPackage to the wiki, please zip it first.
deformation algorithms could be appliedHave Fun!
+
</div>
  
 +
| style="width: 40%; background: #FFFFFF; border: 1px solid #AAA; vertical-align: top;" |
 +
<div style="background: #787878; border: 1px solid #131313; padding: 5px; margin: 3px; font-weight: bold; text-align: center; font-size: 120%;">Notes</div>
 +
<div style="padding-left: 1em;">
 +
Special thanks to [[User:Aarku|Aarku]], [[User:Dho|Dho]], [[User:NCarter|NCarter]], [[User:KeliHlodversson|Freyr]], [[User:Outcast|Outcast]] and others.
  
== TestSmoothFilter.cs ==
+
We're currently working on [[Special:Statistics|{{NUMBEROFARTICLES}}]] [[Special:Allpages|articles]] about Unity and related subjects.
<javascript>
+
using UnityEngine;
+
using System.Collections;
+
  
/*
+
Please see the [[:Talk:Main Page|discussion page]] of the main page for current goals and status. '''Please read these [[:Help:Contents|general guidelines]] before you begin editing.'''
Apply to any meshed gameobject for smoothing.
+
  
        Works also by replacing MeshFilter with SkinnedMeshRenderer and use sharedMesh
+
To create a new page, add a link to an existing page, then follow the link and edit the new page. It's a good idea to copy the layout from an existing page initially, to ensure that your contribution matches the conventions used in our existing articles.  If you just want to experiment, you can do so in the [[:Unify Community Wiki:Sandbox|sandbox]].
  
At present tests Laplacian Smooth Filter and HC Reduced Shrinkage Variant Filter
+
</div>
*/
+
|-
public class TestSmoothFilter : MonoBehaviour
+
| style="width: 33%; background: #FFFFFF; border: 1px solid #AAA; vertical-align: top;" |
{
+
<div style="background: #787878; border: 1px solid #131313; padding: 5px; margin: 3px; font-weight: bold; text-align: center; font-size: 120%;">Main Sections</div>
 +
<div style="padding-left: 1em;">
 +
* [[Extensions]] - Further extend the functionality of Unity with .NET plugins (suitable for any Unity licence) and native code plugins (for Pro users only).
  
private Mesh sourceMesh;
+
* [[Particle Library]] - Pre-configured particle systems for use in your own projects.
private Mesh workingMesh;
+
+
void Start ()
+
{
+
MeshFilter meshFilter = gameObject.GetComponentInChildren<MeshFilter>();
+
+
// Clone the cloth mesh to work on
+
sourceMesh = new Mesh();
+
// Get the sourceMesh
+
sourceMesh = meshFilter.mesh;
+
// Clone the sourceMesh
+
workingMesh = CloneMesh(sourceMesh);
+
// Reference workingMesh to see deformations
+
skinnedmesh.mesh = workingMesh;
+
+
+
// Apply Laplacian Smoothing Filter to Mesh
+
int iterations = 1;
+
for(int i=0; i<iterations; i++)
+
workingMesh.vertices = SmoothFilter.laplacianFilter(workingMesh.vertices, workingMesh.triangles);
+
//workingMesh.vertices = hcFilter(sourceMesh.vertices, workingMesh.vertices, workingMesh.triangles, 0.0f, 0.5f);
+
}
+
+
// Clone a mesh
+
    private static Mesh CloneMesh(Mesh mesh)
+
    {
+
        Mesh clone = new Mesh();
+
        clone.vertices = mesh.vertices;
+
        clone.normals = mesh.normals;
+
        clone.tangents = mesh.tangents;
+
        clone.triangles = mesh.triangles;
+
        clone.uv = mesh.uv;
+
        clone.uv1 = mesh.uv1;
+
        clone.uv2 = mesh.uv2;
+
        clone.bindposes = mesh.bindposes;
+
        clone.boneWeights = mesh.boneWeights;
+
        clone.bounds = mesh.bounds;
+
        clone.colors = mesh.colors;
+
        clone.name = mesh.name;
+
        //TODO : Are we missing anything?
+
        return clone;
+
    }
+
}</javascript>
+
  
== SmoothFilter.cs ==
+
* [[Programming]] - Unity programming resources
<javascript>
+
using UnityEngine;
+
using System.Collections;
+
using System.Collections.Generic;
+
  
/*
+
* [[Scripts]] - Everything from general purpose effects to debugging.
    MeshSmoothTest
+
+
Laplacian Smooth Filter, HC-Smooth Filter
+
+
MarkGX, Jan 2011
+
*/
+
public class SmoothFilter : MonoBehaviour
+
{
+
/*
+
Standard Laplacian Smooth Filter
+
*/
+
public static Vector3[] laplacianFilter(Vector3[] sv, int[] t)
+
{
+
Vector3[] wv = new Vector3[sv.Length];
+
List<Vector3> adjacentVertices = new List<Vector3>();
+
+
float dx = 0.0f;
+
float dy = 0.0f;
+
float dz = 0.0f;
+
+
for (int vi=0; vi< sv.Length; vi++)
+
{
+
// Find the sv neighboring vertices
+
adjacentVertices = MeshUtils.findAdjacentNeighbors (sv, t, sv[vi]);
+
+
if (adjacentVertices.Count != 0)
+
{
+
dx = 0.0f;
+
dy = 0.0f;
+
dz = 0.0f;
+
+
//Debug.Log("Vertex Index Length = "+vertexIndexes.Length);
+
// Add the vertices and divide by the number of vertices
+
for (int j=0; j<adjacentVertices.Count; j++)
+
{
+
dx += adjacentVertices[j].x;
+
dy += adjacentVertices[j].y;
+
dz += adjacentVertices[j].z;
+
}
+
+
wv[vi].x = dx / adjacentVertices.Count;
+
wv[vi].y = dy / adjacentVertices.Count;
+
wv[vi].z = dz / adjacentVertices.Count;
+
}
+
}
+
+
return wv;
+
}
+
+
/*
+
HC (Humphrey’s Classes) Smooth Algorithm - Reduces Shrinkage of Laplacian Smoother
+
+
Where sv - original points
+
pv - previous points,
+
alpha [0..1] influences previous points pv, e.g. 0
+
beta  [0..1] e.g. > 0.5
+
*/
+
public static Vector3[] hcFilter(Vector3[] sv, Vector3[] pv, int[] t, float alpha, float beta)
+
{
+
Vector3[] wv = new Vector3[sv.Length];
+
Vector3[] bv = new Vector3[sv.Length];
+
+
  
+
* [[Shaders]] - Specialised shaders to make your materials more refined.
// Perform Laplacian Smooth
+
wv = laplacianFilter(sv, t);
+
+
// Compute Differences
+
for(int i=0; i<wv.Length; i++)
+
{
+
bv[i].x = wv[i].x - (alpha * sv[i].x + ( 1 - alpha ) * sv[i].x );
+
bv[i].y = wv[i].y - (alpha * sv[i].y + ( 1 - alpha ) * sv[i].y );
+
bv[i].z = wv[i].z - (alpha * sv[i].z + ( 1 - alpha ) * sv[i].z );
+
}
+
+
List<int> adjacentIndexes = new List<int>();
+
+
float dx = 0.0f;
+
float dy = 0.0f;
+
float dz = 0.0f;
+
+
for(int j=0; j<bv.Length; j++)
+
{
+
adjacentIndexes.Clear();
+
+
// Find the bv neighboring vertices
+
adjacentIndexes = MeshUtils.findAdjacentNeighborIndexes (sv, t, sv[j]);
+
+
dx = 0.0f;
+
dy = 0.0f;
+
dz = 0.0f;
+
+
for (int k=0; k<adjacentIndexes.Count; k++)
+
{
+
dx += bv[adjacentIndexes[k]].x;
+
dy += bv[adjacentIndexes[k]].y;
+
dz += bv[adjacentIndexes[k]].z;
+
+
}
+
+
wv[j].x -= beta * bv[j].x + ((1 - beta) / adjacentIndexes.Count) * dx;
+
wv[j].y -= beta * bv[j].y + ((1 - beta) / adjacentIndexes.Count) * dy;
+
wv[j].z -= beta * bv[j].z + ((1 - beta) / adjacentIndexes.Count) * dz;
+
}
+
+
return wv;
+
}
+
}</javascript>
+
  
== MeshUtils.cs ==
+
* [[Wizards]] - Scripts to extend the Unity editor.
<javascript>
+
</div>
using UnityEngine;
+
| style="width: 33%; background: #FFFFFF; border: 1px solid #AAA; vertical-align: top;" |
using System.Collections;
+
<div style="background: #787878; border: 1px solid #131313; padding: 5px; margin: 3px; font-weight: bold; text-align: center; font-size: 120%;">Extras</div>
using System.Collections.Generic;
+
<div style="padding-left: 1em;">
  
/*
+
* [[Tips|Tips, Tools & Tricks]] - Tips and tricks for editing Unity content and supported tools & applications.
Useful mesh functions
+
*/
+
public class MeshUtils : MonoBehaviour
+
{
+
// Finds a set of adjacent vertices for a given vertex
+
// Note the success of this routine expects only the set of neighboring faces to eacn contain one vertex corresponding
+
// to the vertex in question
+
public static List<Vector3> findAdjacentNeighbors ( Vector3[] v, int[] t, Vector3 vertex )
+
{
+
List<Vector3>adjacentV = new List<Vector3>();
+
List<int>facemarker = new List<int>();
+
int facecount = 0;
+
+
// Find matching vertices
+
for (int i=0; i<v.Length; i++)
+
if (Mathf.Approximately (vertex.x, v[i].x) &&
+
Mathf.Approximately (vertex.y, v[i].y) &&
+
Mathf.Approximately (vertex.z, v[i].z))
+
{
+
int v1 = 0;
+
int v2 = 0;
+
    bool marker = false;
+
+
// Find vertex indices from the triangle array
+
for(int k=0; k<t.Length; k=k+3)
+
if(facemarker.Contains(k) == false)
+
{
+
v1 = 0;
+
v2 = 0;
+
marker = false;
+
+
if(i == t[k])
+
{
+
v1 = t[k+1];
+
v2 = t[k+2];
+
marker = true;
+
}
+
  
if(i == t[k+1])
+
* [[Tutorials]] - Tutorials for all things Unity.  These are usually of larger scope than [[Tips|Tips and Tricks]].
{
+
v1 = t[k];
+
v2 = t[k+2];
+
marker = true;
+
}
+
+
if(i == t[k+2])
+
{
+
v1 = t[k];
+
v2 = t[k+1];
+
marker = true;
+
}
+
+
facecount++;
+
if(marker)
+
{
+
// Once face has been used mark it so it does not get used again
+
facemarker.Add(k);
+
  
// Add non duplicate vertices to the list
+
* [[Contests]] - User contests for fun and fame!
if ( isVertexExist(adjacentV, v[v1]) == false )
+
{
+
adjacentV.Add(v[v1]);
+
//Debug.Log("Adjacent vertex index = " + v1);
+
}
+
+
if ( isVertexExist(adjacentV, v[v2]) == false )
+
{
+
adjacentV.Add(v[v2]);
+
//Debug.Log("Adjacent vertex index = " + v2);
+
}
+
marker = false;
+
}
+
}
+
}
+
+
//Debug.Log("Faces Found = " + facecount);
+
+
        return adjacentV;
+
}
+
+
+
// Finds a set of adjacent vertices for a given vertex
+
// Note the success of this routine expects only the set of neighboring faces to eacn contain one vertex corresponding
+
// to the vertex in question
+
public static List<int> findAdjacentNeighborIndexes ( Vector3[] v, int[] t, Vector3 vertex )
+
{
+
List<int>adjacentIndexes = new List<int>();
+
List<Vector3>adjacentV = new List<Vector3>();
+
List<int>facemarker = new List<int>();
+
int facecount = 0;
+
+
// Find matching vertices
+
for (int i=0; i<v.Length; i++)
+
if (Mathf.Approximately (vertex.x, v[i].x) &&
+
Mathf.Approximately (vertex.y, v[i].y) &&
+
Mathf.Approximately (vertex.z, v[i].z))
+
{
+
int v1 = 0;
+
int v2 = 0;
+
    bool marker = false;
+
+
// Find vertex indices from the triangle array
+
for(int k=0; k<t.Length; k=k+3)
+
if(facemarker.Contains(k) == false)
+
{
+
v1 = 0;
+
v2 = 0;
+
marker = false;
+
+
if(i == t[k])
+
{
+
v1 = t[k+1];
+
v2 = t[k+2];
+
marker = true;
+
}
+
  
if(i == t[k+1])
+
* [[Unity Projects]] - Community development efforts to extend Unity.
{
+
v1 = t[k];
+
v2 = t[k+2];
+
marker = true;
+
}
+
+
if(i == t[k+2])
+
{
+
v1 = t[k];
+
v2 = t[k+1];
+
marker = true;
+
}
+
+
facecount++;
+
if(marker)
+
{
+
// Once face has been used mark it so it does not get used again
+
facemarker.Add(k);
+
  
// Add non duplicate vertices to the list
+
* [[IRC|IRC Chatroom]] - Your portal to the Unity community.
if ( isVertexExist(adjacentV, v[v1]) == false )
+
 
{
+
* [[Unify Community Wiki:Community Portal|Community Portal]] - Your portal to the Unity community.
adjacentV.Add(v[v1]);
+
</div>
adjacentIndexes.Add(v1);
+
| style="width: 33%; background: #FFFFFF; border: 1px solid #AAA; vertical-align: top;" |
//Debug.Log("Adjacent vertex index = " + v1);
+
<div style="background: #787878; border: 1px solid #131313; padding: 5px; margin: 3px; font-weight: bold; text-align: center; font-size: 120%;">Support Unify Wiki</div>
}
+
<div style="padding-left: 1em;">
+
 
if ( isVertexExist(adjacentV, v[v2]) == false )
+
*[http://www.dreamhost.com/donate.cgi?id=9231 Donate towards hosting of this wiki!]
{
+
 
adjacentV.Add(v[v2]);
+
*[http://www.printfection.com/unifycommunity/ Unify Community Merch]
adjacentIndexes.Add(v2);
+
 
//Debug.Log("Adjacent vertex index = " + v2);
+
*Please see [http://meta.wikipedia.org/wiki/MediaWiki_i18n documentation on customizing the interface] and the [http://meta.wikipedia.org/wiki/MediaWiki_User%27s_Guide MediaWiki User's Guide] for usage and configuration help.
}
+
 
marker = false;
+
</div>
}
+
}
+
}
+
+
//Debug.Log("Faces Found = " + facecount);
+
+
        return adjacentIndexes;
+
}
+
+
// Does the vertex v exist in the list of vertices
+
static bool isVertexExist(List<Vector3>adjacentV, Vector3 v)
+
{
+
bool marker = false;
+
foreach (Vector3 vec in adjacentV)
+
  if (Mathf.Approximately(vec.x,v.x) && Mathf.Approximately(vec.y,v.y) && Mathf.Approximately(vec.z,v.z))
+
  {
+
      marker = true;
+
  break;
+
  }
+
 
+
return marker;
+
}
+
}
+
</javascript>
+

Revision as of 00:40, 16 January 2012

Welcome to the UnifyWiki
The UnifyWiki is part of the Unify Community and is a place to find and share Unity knowledge.


Splash.jpg
Wiki News
  • IMPORTANT: syntax highlighting now uses different tags. Where you previously could write <csharp>, <javascript> or <boo>, you now have to write <syntaxhighlight lang="csharp">. The names used for each language have not changed. You can learn more about the syntax highlighter's features here.
  • The spam filter has been tightened a bit. If the wiki refuses an edit because it says it's spam and you don't know why, please contact an administrator.
  • It is possible to upload zip archives to the Unify wiki. We encourage you to provide a zipped copy of your script or shader when adding a new article, as this will help to avoid problems with various web browsers where garbage characters are introduced into text which is copied and pasted from these pages.
  • The maximum file size for any uploaded file is now 512KB, and this includes images as well as zip files. Unfortunately, unityPackage files are not directly supported at present, as we have been unable to make MediaWiki recognise the unusually long filename extension. If you wish to add a unityPackage to the wiki, please zip it first.
Notes

Special thanks to Aarku, Dho, NCarter, Freyr, Outcast and others.

We're currently working on 818 articles about Unity and related subjects.

Please see the discussion page of the main page for current goals and status. Please read these general guidelines before you begin editing.

To create a new page, add a link to an existing page, then follow the link and edit the new page. It's a good idea to copy the layout from an existing page initially, to ensure that your contribution matches the conventions used in our existing articles. If you just want to experiment, you can do so in the sandbox.

Main Sections
  • Extensions - Further extend the functionality of Unity with .NET plugins (suitable for any Unity licence) and native code plugins (for Pro users only).
  • Particle Library - Pre-configured particle systems for use in your own projects.
  • Scripts - Everything from general purpose effects to debugging.
  • Shaders - Specialised shaders to make your materials more refined.
  • Wizards - Scripts to extend the Unity editor.
Extras
  • Tips, Tools & Tricks - Tips and tricks for editing Unity content and supported tools & applications.
  • Contests - User contests for fun and fame!
Support Unify Wiki
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox