Vector math makes my head hurt so I’m hoping you can help me out here…
I’ve got a plant generator that creates plant data as point clouds. The points start at a pivot point (0,0,0) and continue upward using an up vector (0,1,0). This plant data is then instanced all over a generated landscape.
Unfortunately the landscape is spherical, so I need to change the up vector for each instance, and that’s where my head starts to hurt. Up till now I’ve cheated using empty game objects, but that’s no longer an option.
So if you have an array of points, an offset position, a pivot and an up vector, and you change the up vector, how would you find the new local positions for each point?
you can create the plant and rotate its transform, just like you would any other gameobject that is to be on this sphere’s surface
OR
if you want to get the up vector to use as a seed to create a new plant. Any you know the location on the sphere this plant that you need the seed up vector for is.
a vector in the direction from A to B is (A - B)
Then the up vector would be (posOfPlant - centerOfSphere).normalized [we normalize so it’s a unit vector]
Growing a new plant using a different up vector is no problem, but it’s much faster to just grow 100 plants and instance them 1000 times than to grow 100,000 plants from scratch. That’s why I’m looking for ways to transform the point cloud.
In a perfect world I would just instance a gameobject and transform it. But the plant data is just an array of Vector3s, and I need to preserve the points for later use. So I’m stuck transforming them manually.
If we assume it’s not an option to cheat this using gameobjects, how would you do the math?
If you don’t want to use Gameobjects, why are you using Unity and not, for example XNA? How are you drawing your point cloud?
And I’m guessing I was not clear enough my first post…
In any case, I’ll assume, you have a set of vectors AND a single parent gameobject that has a transform. So one gameobject per “tree” of vectors. You want to do a rotation for example.
Use the parent gameobject transform to extract the world matrix.
With all children vectors you have to 1) transform all points to world space (localToWorld) and then 2) transform all points by a rotation, then 3) transform back to localSpace (as they are stored this way). Finally Transform your parent gameobject by the same rotation in step 2.
And if you need to actually rotate existing vectors. Look at Quaternions. Create a quaternion rotation from Vector3.up to the new surface normal. Then just transform every vector in the plant by that quaternion.
That would work fine if there was only one tree. I think what he was trying to say is he is generating his vectors in local space (I think dynamically building a tree), and indeed the only pratical means to do this is in local space. But his transforms are done in world space. I think unlike something like DirectX or XNA, Unity insists you use thier Transform system. Thats the nature of the beast.
Thankfully this is an isolated case, the rest of my world objects are standard game objects.
But in this case, all I have to work with is laid out in the initial post - an array of vectors, an offset position, a pivot and an up vector. There’s no parent object or anything - just a raw array of Vector3s. So assume that we’re not using game objects in any way shape or form.
I’ve found some posts that kinda-sorta get into this but I don’t think they address this exact. Or maybe they do and I’m just not understanding them:
Yes of course, but you were suggesting creating / manipulating game objects - this is a game object-free scenario. These plants only exist as raw point clouds. I can generate a new set of points from scratch using any up vector I want, but that’s slow, so my goal is to generate these points once using one up vector, and then manually transform them to align with different up vectors. All without the aid of game objects.
No game objects at all? Are you sure? Hrmmmmm…
How many trees are required in your project, surely one per tree won’t hurt?
Or even just have one for the central earth?
Haha, somehow I knew people would be asking ‘why torture yourself.’
Here’s the skinny.
I generate the point cloud, and then use that data to generate several meshes - branches, foliage, etc. Those are obviously attached to game objects.
If I could just rely on those meshes from that point forward, I’d discard the points and transform the meshes like any normal object.
Unfortunately I need to keep the points around so I can interact with the plants later, in a really specific way. I tried other methods - using the mesh vertices for instance - but they didn’t pan out.
Up till now I’ve been using empty game objects to store the points. I kept them parented them to the game object with the meshes. That works OK for a couple of hundred plants. But for hundreds of thousands, it’s way too inefficient. So I stopped using empty game objects and started using points.
Overall the system works great, but now that I want to instance the data the points are a headache.
Here are some pics of the trees, they’re really lovely when they’re behaving…
Ok so we can expect (500 - 5000) = average 2750 points per plant.
2750 x 300,000 plants = 825000000.
Assume you have a List of Vectors and each point is only 1 vector (absurdly generous, not taking into account list space, colours, etc).
12 bytes at least for a 3D vector.
12 x 825000000 = 9900000000. Nearly 10 Gb.
Even vectors aren’t small enough for what you want.
You need to figure out an occlusion and LOD system.
Way ahead of you. I store the points in a sparse array and load / unload them as needed, using an occlusion / LOD system.
This is why I tried to keep the question limited to: how do you transform a vector using a pivot, offset and up vector. I knew that if I got into the why, it would become a game of ‘you can’t do that.’ But really, the system works great. This step is only problematic because I suck at math.
So if we assume that the system’s working and turn towards the math, do you have any thoughts?
Bear in mind for what you want you will need to be streaming data off something bigger than your RAM.
If you had such a data streaming + occlusion system then why aren’t you using GameObjects ?
In any case I already pointed out the solution and the problem. You need some way of getting the World Matrix. Without a transform I’m not sure how.
You can build a 4x4 rotation matrix (Angle based) or use a Quaternion (Axis based) to do the rotation. If you multiply your vector with a matrix or quaternion the result will be the transformed vector. After the transform happens you need to put the data back to its local coordinates (assuming the drawing has taken place).
Without gameobjects this doesn’t really translate to Unity that well, why not use XNA?
I’m streaming it to/from disk. But using points has as much to do with generation speed as storage - it’s much, much faster to create the point cloud if I’m not creating all those game objects along with it. We’re talking minutes vs. seconds.
It’s a fair question, the answer is outside of this foliage system, Unity does everything that I need and more. So I’m OK with doing things the hard way for maybe 10% of the time, and then having it easy the other 90%.
OK, well at least that whittles the question down to, how do I get a World Matrix out of an offset, a pivot and an up vector, without the aid of a transform. (It sounds almost like the setup for a joke, haha.)
Know anyone around these parts who’s immersed in that kind of math?
Its nothing to do with the maths. Its the engine.
I just don’t think Unity likes letting you do things that way.
Maybe you could write a shader to do it, I know you can get the low level stuff (World matrix) you need there.
Hey - sorry I missed your third suggestion. What’s the process for getting a quaternion from one up vector to the next? There are so many ways to manipulate Quaternions, I don’t know where to start.