ingress-model-viewer
ingress-model-viewer copied to clipboard
Q: How dynamic meshes are generated?
Haven't been here for a long time. Howdy.
This project is more a learning material to me than a project that I can really participate in. And at the moment I have trouble understanding how the dynamic meshes, such as the Link, are generated.
The function _generateLinkAttributes
is used to generate vertex data, and the _generateFaces
for index data, which will be used in glDrawElements
. But I can't understand the detail in _generateLinkAttributes
.
Here are some questions with the Link:
- How are the vertices generated and organised?
- I know a bit but want some more detailed information.
- How to achieve the 3D feeling for a Link?
- In my implementation I only receive a streaming plane.
- What's the best way if I want to remove the shadow below a link?
- Looks like a texture and shader stuff, but I don't have any clue at the moment.
Thanks in advance.
You know, this is something I've wanted to make a little animation to demonstrate, because it's actually pretty cool. We'll go over the portal link, since it's only slight more complicated than the resonator link. The code in _generateLinkAttributes
is kind of unreadable, but it's because I reverse engineered it from the game client and was only able to really figure out what a portion of the variables were for. Some of them are probably just added in by the compiler for optimizations or whatever.
Basically, the way the link geometry works is that it splits the link up into 8 equal pieces, so needs to generate 9 sets of vertices. In other words, it'll generate the start vertices, then the end of the first 1/8th, then the end of the second, and so forth, until each segment has both start and end vertices.
It uses some pre-generated values to describe the general outline of the link (c
, d
, and e
), but aside from that, the rest is just a bunch of geometry maths. If you were to take a cross-section of the link, it would look like a lowercase t.
To generate this, it needs to calculate 6 vertices. The first pair are the left and right edges of the "t". The second pair are the top of the "t", and a point about halfway down the leg. The last pair are the base of the "t" and the point of intersection between the two lines that make it up.
It fills these into the buffer in a staggered pattern, so when it's done generating the vertices, they're packed in with all the left/right vertices, then all the top/bottom of the upper vertical plane, then all the top/bottom of the lower vertical plane.
When they're packed in this manner, it makes generating the faces much quicker, since it can just "walk" down each set of these vertices and lace everything up accordingly.
As far as making the "upper" portion of the link look like it has a circular cross-section? That's handled by the shader. It calculates the angle between the camera and the various planes, and modulates the transparency accordingly. The closer the camera facing vector is to the direction of one of the planes, the more transparent it becomes.
However, the default shader is somewhat optimized, and really doesn't work well if you move away from the fixed-viewpoint of the game. I ran into this issue when making the spherical portal links; you'll notice they're generated in mostly the same way, but they provide just a little bit more information.
Looking at the differences between the link3d
shader (in static/
) and the LinkShader
(in manifest/assets.json
) should reveal some of the changes needed to make it work well in full 3-space.
In fact, you might be able to find a middle ground between the spherical-portal-link
geometry and the portal-link
geometry that lets you use the link3d
shader, but not have spherical links at all.
I'll see if I can make the demo, as well, as this explanation can only go so far with words alone :)
Many thanks for your long detailed clarification, I am trying to gain an insight into it :)
Going to make a note and say I'll try to generate an animation that demonstrates the explanation above, but it'll be pretty far out at 0.24.0.
It's also worth pointing out that this project will become more of a historical artifact in the coming months... Ingress is moving away from libgdx, which this library emulates (some parts of), and I believe is moving to a Unity engine, instead.