Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
avatar image
1
Question by Edwards0 · Jan 23, 2016 at 01:29 AM · procedural generationquaternionstree creatortransformdirection

Problem with Windswept Procedural tree

I am new to Unity and trying my first project. In the project I need a specific type of windswept tree that players climb so I want the tree as realistic as possible. The Unity-generated tree produces square branches for the smaller ones. I wanted something more realistic. I grabbed "Procedural Tree" (https://www.assetstore.unity3d.com/en/#!/content/32907) from the asset store. It makes nice trees, round branches,... but not windswept. I went into the code and tried to modify the rotations to preferentially have the limbs bend in a specific world direction. I can't seem to get the rotations correct. I can bend the branches but the orthogonal rings don't rotate (the branches turn inside out) or I can bend them in the local system and get corkscrew trees - interesting but not what I need. I have never worked with quaternions so that it where I am messed up.

It is clear that my use of transform.InverseTransformDirection is incorrect. I have tried it using quaternions instead of vector components, rotating the quaternion toward an object. switching the entire code to vectors,... not having much luck. I have contacted wasabimole who wrote the code a couple of times but haven't heard back from them.

Any help would be greatly appreciated. What I need are suggestions on the best and simplest way to do this and hints to understand what is happening so I can do it myself in the future.

Thank you in advance.

The recursive branch code with my modifications is:

 // Add ring vertices
 for (var n = 0; n <= NumberOfSides; n++, ang += angInc) 
 {
     var r = ringShape[n] * radius;
     offset.x = r * Mathf.Cos(ang); // Get X, Z vertex offsets
     offset.z = r * Mathf.Sin(ang);
     vertexList.Add(position + quaternion * offset); // Add Vertex position
     uvList.Add(texCoord); // Add UV coord
     texCoord.x += textureStepU;
 }
 
 if (lastRingVertexIndex >= 0) // After first base ring is added ...
 {
     // Create new branch segment quads, between last two vertex rings
     for (var currentRingVertexIndex = vertexList.Count - NumberOfSides - 1; currentRingVertexIndex < vertexList.Count - 1; currentRingVertexIndex++, lastRingVertexIndex++) 
     {
         triangleList.Add(lastRingVertexIndex + 1); // Triangle A
         triangleList.Add(lastRingVertexIndex);
         triangleList.Add(currentRingVertexIndex);
         triangleList.Add(currentRingVertexIndex); // Triangle B
         triangleList.Add(currentRingVertexIndex + 1);
         triangleList.Add(lastRingVertexIndex + 1);
     }
 }
 
 // Do we end current branch?
 radius *= RadiusStep;
 if (radius < MinimumRadius || vertexList.Count + NumberOfSides >= MaxNumVertices + 65000) // End branch if reached minimum radius, or ran out of vertices
 {
     // Create a cap for ending the branch
     vertexList.Add(position); // Add central vertex
     uvList.Add(texCoord + Vector2.one); // Twist UVs to get rings effect
     for (var n = vertexList.Count - NumberOfSides - 2; n < vertexList.Count - 2; n++) // Add cap
     {
         triangleList.Add(n);
         triangleList.Add(vertexList.Count - 1);
         triangleList.Add(n + 1);
     }
     return; 
 }
 
 // Code added for windswept tree
 var x = (transform.InverseTransformDirection(0f,0f,1f).x);
 var y = (transform.InverseTransformDirection(0f,0f,1f).y);
 var z = (transform.InverseTransformDirection(0f,0f,1f).z);
 position += quaternion * new Vector3(x, (y + SegmentLength * Mathf.Sqrt (Mathf.Sqrt(radius))), z);
 transform.Rotate(x, y, z);
 // Code added for windswept tree


 x += (Random.value - 0.5f) * Twisting;
 y += 0f;
 z += (Random.value - 0.5f) * Twisting;
 
 transform.Rotate(x, y, z);
 
 // Continue current branch (randomizing the angle)
 texCoordV += 0.0625f * (SegmentLength + SegmentLength / radius);
 
 lastRingVertexIndex = vertexList.Count - NumberOfSides - 1;
 Branch(transform.rotation, position, lastRingVertexIndex, radius, texCoordV); // Next segment
 
 // Do we branch?
 if (vertexList.Count + NumberOfSides >= MaxNumVertices || Random.value > BranchProbability) return;
 
 // Yes, add a new branch
 transform.rotation = quaternion;
 x = Random.value * 70f - 35f;
 x += x > 0 ? 10f : -10f;
 y = 0f;
 z = Random.value * 70f - 35f;
 z += z > 0 ? 10f : -10f;
 transform.Rotate(x, 0f, z);
 
 Branch(transform.rotation, position, lastRingVertexIndex, radius, texCoordV);

}

Comment
Add comment · Show 6
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 cjdev · Jan 23, 2016 at 03:21 AM 0
Share

What are ringShape and quaternion and how are they made?

avatar image Edwards0 cjdev · Jan 23, 2016 at 04:37 AM 0
Share

cjdev,

ringShape is a parameter supplied by the user that makes the branch round or more random shape - a bit more natural shaped. See SetTreeRingShape() in the code below

quaternion is passed to the recursive branch routine. $$anonymous$$y understanding is that there is a position - passed as "position" to the branch subroutine - vector used to give the location and direction of the next segment of the branch. Also transform.rotation is passed and this is the quaternion it uses. I can change the position vector as needed to give me the windswept tree but not the corresponding transform.rotation so the corresponding ring for the segment is not orthogonal to the segment axis. This is the crux of the problem. $$anonymous$$y lack of knowledge on quaternions is where I have problems.

Below is the full code including the segment above... sorry I didn't want to paste too much...

avatar image cjdev cjdev · Jan 23, 2016 at 05:42 AM 0
Share

I don't think it will let you post that much code in the comments, but from what I can see it looks like ringShape is a modifier that deter$$anonymous$$es the offset of the verts from a circle. And then quaternion is what deter$$anonymous$$es the direction and facing of the circle. If you want to modify the direction of the tree branches I think your best bet would be to modify the position and quaternion directly. Ins$$anonymous$$d of trying to visualize quaternions in general though I'd recommend using Unity's helper methods, like Quaternion.Euler. $$anonymous$$ultiplying your slight rotation by quaternion every circle and tweaking the position a bit should get you close to some windswept branches.

avatar image Edwards0 cjdev · Jan 23, 2016 at 07:01 AM 0
Share

cjdev,

I tried to post the code though it is in moderation at the moment. It is available at the asset store but for now I appreciate any insights you might have.

Yes, I have been able to modify just the position and get nice windswept trees but the the ring of vertices goes from orthogonal to 45 degree tilt to parallel to the direction to more than 90 degree... at this point the branches turn inside out and the mesh gets destroyed - collisions are wrong, colors are weird...branches look like flat ribbons and half tubes.

The original author was able to bend the branches correctly when the twisting component is implemented - just below where I added my piece of code. I was hoping to repeat this only in a consistent world direction.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Jan 26, 2016 at 04:36 AM

I just had a look at your added code. Well, there are a few things strange / wrong. InverseTransformDirection transforms a worldspace direction into a local space direction. "localspace" inside the branch however means local to the current section as he's adjusting the transform position / rotation for each step. This is reverted when the tree creation is finished. He basically uses the Transform as temp position / rotation marker.

So your x,y and z values would now contain the local space equivalent of the world space vector (0,0,1). I'm not sure why you rotate that vector by the quaternion value as this would basically revert the vector back to (0,0,1).

You then shift the next branch step by this vector which would still make a bit of sense. However using the same values in Rotate makes not much sense. The vector is a normalized vector while Rotate() takes angles in degrees.

I've just downloaded the original asset from the assetstore and added "some code" for a "wind" parameter. The script now has an additional "windStrength" variable and a vector to define the direction of the wind. That vector is in local space of the tree object (not local to each branch). I also added an "worldWindSource" Transform variable which allows you to assign an empty gameobject. If a gameobject is provided the script will use the objects forward vector as wind direction and convert it into local space.


The modified script can be found here.


I enclosed all changes with comments like this:

 // <windswept>
   the changes
 // </windswept>

So if you want to know what i changed, just look out for those or use the search function and search for "".

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 Edwards0 · Jan 27, 2016 at 03:20 AM 0
Share

Bunny83,

Thank you for the answer. It looks great!! The tree truly has the windswept look and the branches hold their shape. I will have to go through it in detail to understand what you did but I really appreciate your help. Thanks! If you need anything I can help with in the future just let me know. I fI get through this I will also send you a version of what I am making... it should be fun.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Can I create a tree using L-systems without having to instantiate each branches ? 2 Answers

Relative Rotations and Position calculation 2 Answers

Good Solution for Camera Movement 4 Answers

TransformDirection and Scale 1 Answer

Gyroscope Magnetic North. 1 Answer


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