Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Mar 14, 2015 at 07:09 PM by meat5000 for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by commodore · Mar 14, 2015 at 04:57 PM · c#loopefficiency

How can I make this code more efficient?

This loops through each vertex in pieceMesh, finds the closest vertex to it in tempPieceMesh and copies its boneweights. I'm using nested for loops to go through each vertex so it takes a second or two to run through. I was hoping to be able to cut that time down as it will have to do this for a few more meshes.

 Mesh pieceMesh = piece.GetComponent<SkinnedMeshRenderer>().sharedMesh;
 Mesh tempPieceMesh = tempPiece.GetComponent<SkinnedMeshRenderer>().sharedMesh;
 BoneWeight[] weights = tempPieceMesh.boneWeights;
 
 // Iterate through piece's vertices, find closest vertice in tempPieceMesh and copy its boneweights
 for(int i = 0; i < pieceMesh.vertexCount; i++)
 {
     // Check vertex distance. If there is a higher one, set verDistance to it
     float checkVertDis = 0.0f;
     float vertDistance = 10.0f;
 
     for(int j = 0; j < tempPieceMesh.vertexCount; j++)
     {
         checkVertDis = Vector3.Distance(pieceMesh.vertices[i], tempPieceMesh.vertices[j]);
 
         // If we find a lower distance, set vertdistance to it and copy the boneweights
         if(checkVertDis < vertDistance)
         {
             vertDistance = checkVertDis;
 
             weights[i] = tempPieceMesh.boneWeights[j];
         }
     }
 }
 pieceMesh.boneWeights = weights;


Edit: Here's the fixed code using @CHPedersen's advice:

 Mesh pieceMesh = piece.GetComponent<SkinnedMeshRenderer>().sharedMesh;
 Mesh tempPieceMesh = tempPiece.GetComponent<SkinnedMeshRenderer>().sharedMesh;
 BoneWeight[] weights = tempPieceMesh.boneWeights;
 BoneWeight[] newWeights = pieceMesh.boneWeights;

 // Copy the positions of pieceMesh and tempPieceMesh vertices into new array to use in distance function
 Vector3[] pVertices = pieceMesh.vertices;
 Vector3[] tPVertices = tempPieceMesh.vertices;                  

 // Iterate through piece's vertices, find closest vertice in tempPieceMesh and copy its boneweights
 for(int i = 0; i < pieceMesh.vertexCount; i++)
 {
     // Check vertex distance. If there is a higher one, set verDistance to it
     float checkVertDis = 0.0f;
     float vertDistance = 10.0f;

     for(int j = 0; j < tempPieceMesh.vertexCount; j++)
     {
         checkVertDis = Vector3.Distance(pVertices[i], tPVertices[j]);

         // If we find a lower distance, set vertdistance to it
         if(checkVertDis < vertDistance)
         {
             vertDistance = checkVertDis;

             newWeights[i] = weights[j];
         }
     }
 }
 pieceMesh.boneWeights = newWeights;






Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image maccabbe · Mar 14, 2015 at 05:11 PM 0
Share

Use an octree

http://en.wikipedia.org/wiki/Octree

avatar image Owen-Reynolds · Mar 14, 2015 at 05:25 PM 0
Share

This looks like a pure modelling thing. I mean, $$anonymous$$ax and blender do this for auto-set bone weights, probably based on a standard algorithm. I'd imagine that technical modelling forums would have more info.

avatar image commodore · Mar 14, 2015 at 05:53 PM 0
Share

@Owen Reynolds

I'm creating a system that lets you sag the character's pants at runtime using a slider and blendshapes. Here's an image showing what I was trying to achieve.

http://i.imgur.com/t2OTas9.jpg

piece is the image on the left and tempPiece is the image on the right.

The problem was that the vertices no longer deformed correctly. The vertices that were supposed to bend at the knees bent at the shins ins$$anonymous$$d. The code fixes the deformation by copying the weights of the closest vertex in tempPiece to piece but it takes a little while to go through the loops. I'm looking for ways to make it more efficient.

1 Reply

  • Sort: 
avatar image
1
Best Answer

Answer by CHPedersen · Mar 14, 2015 at 06:02 PM

By far the worst performance drawback of that code snippet is that you're accessing Mesh.vertices inside the for-loop. That property looks innocent, but Unity is in fact instantiating and returning a deep copy every time you access it, which adds an incredibly unnecessary overhead on each access of pieceMesh.vertices[i] and tempPieceMesh.vertices[j], especially if that mesh has a lot of vertices.

Copy out the vertex arrays ONCE outside the for loop, then index into that copy to do your distance calculations.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image commodore · Mar 14, 2015 at 07:05 PM 0
Share

Thank you! I edited the code in the OP with your advice.

It now takes 17 ms ins$$anonymous$$d of 3832 ms

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Increase value through frames, or in a while? 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

C# Code efficiency. 1 Answer

Checking an array variable in C# vs JavaScript 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges