Membrane

For those of you that are not on Slack, I’m TheCreator and I have recently been self-assigned the tenuous task of designing the cell membrane. Having only taken one Java programming class up to date, I am mostly self-taught, so I cannot make any promises, but I will do my best to make an amazing membrane.

Also from the Slack discussion, I originally thought this was a super simple task. I mean, I can easily draw a curve around a bunch of hexagons, how hard can it be to make a computer do this? Well, it is very hard—apparently computers are incredibly dumb. Eventually after many painstakingly long hours (my laptop says I spent 6 hours on this prototype :frowning: ) I managed to create a bunch of points based on the arrangement of the organelles that the computer only needs to connect. I thought the hard part was behind me. I was wrong again. Computers need the points to be located in a specific pattern before they can connect them. This led to me spending two more hours writing an algorithm that could put order to disorganized points and then connect them. Here are the results.

My current prototype is in 2D and uses a combination of bezier curves and precomputed slopes to draw the membrane. This means that the membrane can be scaled infinitely and it will still look good. After a bit more cleaning up I will rewrite my code to work in 3D (probably using bezier surfaces) and eventually will add color using OpenGL shaders.

For now I will refrain from going deep into technical stuff and will simply ask you guys a question: Which of the following images looks the best? I made it wavy and cell-like, but now that I think about it looks too much like a fish and too little like a microorganism, so I will try to get rid of them and edit in another image.

The small circles in the center are the organelles and the big one is the nucleus.

EDIT: Apparently the waviness was caused by a bug :confused: (unless you guys like it, then it could become a feature). So here is the new version:

Is everyone fine with this? In that case, I have an important question for @crovea: how exactly do you want me to output the points for my 3D membrane? Should I attempt to put it into .obj format or is there an easier/more preferred way?

Another question for @Oliveriver, you wanted the membrane to be flexible and moveable. By moving the control points for the bezier curves, you can change the membrane a bit. Is this enough, or did you want something else?

All comments and critiques welcome!

3 Likes

Awesome work! :smiley:

The non-bug version looks the best, although I also quite like the second of the bug versions, even if it’s not quite so realistic. Would you mind showing some more examples of how the algorithm adapts to other hexagon/cytoplasm/organelle arrangements?

Moving the points of the curves should be ok, although you’d have to add an extra layer of code for detecting collisions and telling the algorithm which points to move in response. @tjwhale got quite a nice looking pseudopodial movement system towards the end of this thread:

Also some of it might be redundant now, but this thread was where work on the membrane was originally discussed, and it lays out some of the requirements for the finished product (along with what’s in the visuals page of the GDD):

@Oliveriver: Sorry for taking so long to reply—I didn’t want to write anything until I finished reorganising the code and had something to show. Basically, what I had before was a simple proof of concept that worked only for that arrangement of organelles. Here is an image with a couple cells that came to my mind:

I saw @tjwhales prototype when it was first written and it looks really nice; however I didn’t use it as a base because I wanted to have static cells (for example when the cell is stationary or when it needs to be displayed in the editor) and in his prototype the membrane is in constant motion, even when all the organelles have come to a stop. I was thinking that we could still use it for other cells that rely mostly on pseudopods movement, for example before the player’s cell gains flagella or cilia. I also have no idea how we could make it 3D (other than turning his 2D starting grid into a cube)

Speaking of which, I would really like to hear everyone’s opinions as to how to make my current prototype three-dimensional. Basically, so far I have a couple functions that take in the positions of the organelles and output an array of points that the Render() function simply needs to connect in order.

Here are a couple of my ideas:

  1. Use a bezier surface. This is probably the most obvious one—I am using bezier curves to make my membrane in two dimensions already so why not expand it into the third. However, I have absolutely no idea how bezier surfaces work and this will require a lot of reading and might not work at all in the end.
  2. Take a pre-existing model of a sphere and modify it until its diameter is the 2D membrane I have already. Again, this works in theory, but I really have no idea how to realise it in practice.
  3. Take the polyline that I have and turn it into a prism (should be easy), then take the points in the tops and bottom and move them all to a common center; the rest of the points in the figure should follow proportional to their distances to the top or bottom, respectively. This is my favourite idea, but I am not sure how well it would work for weirdly-shaped membranes (like an S-shape).

I look forward to your commentary and critiques as well as your ideas as to how I could make my membrane 3D.

@TheCreator These are really nice shapes, I think they would be good in the game.

I’m afraid I don’t know much about Bezier curves or surfaces. My guess is if you’ve understood the curves then going to surfaces might not be as hard as you think (as it’s basically the same principle) however I’m not sure.

You could try some simple approximations. Like from each point on the line draw a straight line from there to a central point (a bit like a circus ten or something like that). It might look very angular but it might be a simple way to do it.

In fact you could create a small curve of the same shape which is inside this one but alse a bit higher, then you connect the curves with each other. (This is probably confusing, I’ll draw a picture.)

Like this, so you nest smaller versions of the outer curve inside each other up to a point. The more you put in the smoother it will look. Just a suggestion.

@tjwhale: that is what I meant by my prism approach, but the fact that we both came up with it means it’s a good idea. The problem with doing this, though, is that it doesn’t work for S-shaped cells. As we move the top part closer to the center it stops being directly above the previous layer and creates a really weird shape (if that’s hard to visualize just take me word for it)

Edit: After thinking for the past two hours how I could make the second layer directly above the previous I realized that I have a “Distance” variable that does exactly this :sweat: .

I guess I will try to use bezier surfaces and see what happens. If I can’t get a good result in the next couple of days I will just do what you described.

Also, about you own prototype, it creates a very cell-like behavior and I would really implement the way it moves into the final membrane version. However, there are a couple of comments I have about it:

First, would it be possible to remove the triangles and have it work with only a single outline? Or would that completely mess up the algorithm? I was thinking that maybe we could input my vertex buffer into your program to create realistic movement pseudopodial movement. Second, sometimes when the cell stops moving there are very artificial artifacts on the membrane—the points keep moving in closer toward the organelles and when they get too close they “jump” backward. Is there any way to remove this? Maybe you could try adding an additional constraint that stops the points when they get to a specific point.

I don’t want to force you to do anything, but if you have any free time could you perhaps try this? If you don’t want to do this or what I ask is not possible, it’s really not a problem.

Edit2: I just got an excellent idea. What if I created a prism out of my flat surface (like I originally wanted) and then did a subdivision surface (Catmull-Clark style)? Anybody know how to do that?

@TheCreator

Yeah the triangles are secondary, all the maths is done on the points themselves and then the triangles just follow the points. I thought the triangles were very important for rendering because when you display a polygon you make it out of many triangles, I may be wrong.

My prototype could take a mesh as input. The problem is that each point needs to know it’s neighbours in a sensible way and it uses this to put the triangles in. I found the easiest way to do this was to start with a cube (where it’s relatively easy to detect neighbours and add in the triangles) and then deform it but there’s no principle reason why you couldn’t start with any shape.

The “jump” is created by two things. The way the prototype works is it smooths the surface, then shrinks it a little, then moves it away if it has got too close to any of the organelles. If you want the organelles to move then the speed at which the skin moves away if it is close to them needs to be very fast (otherwise the organelles can get outside the skin briefly). If the organelles don’t move this can be much weaker. I’m sure the “jump” could be replaced with a smoother function, spread over a few frames. The membrane sort of “bubbles” because it is getting shrunk relatively powerfully and then the membrane is being moved away from the organelles when it is too close. A better implementation of this would balance those forces so it sat at a nice distance, as you say.

My issue with doing more is that it doesn’t matter if I perfect my Python prototype. What matters is that we get something in the game. What I want is to wait for a programmer who wants to build this system and then support them to build what they want. If they want to use any or all of my prototype then that’s great, if not that’s totally fine. I want them to feel like they have ownership of building something. I worry I spend a lot of time building prototypes and making demands (this system must have x,y and z) and that it’s hard for someone to want to come and build things with that hanging over them. I’d like someone to feel they are in charge of the membrane and building it is a fun and cool project they can take credit for.

So yeah if there’s anything I can help you with let me know, I’ll happily help. I think I’d rather help anyone on the team than just keep building more myself.

You are completely right here, the graphics card needs to be sent a bunch of triangles for it to render something, otherwise it doesn’t work.

I see. Would it be possible to have a simple curve instead of a mesh, though? If not, then I guess I could just create additional points inside the curve.

Okay, but theoretically it should be possible to eliminate the jump, right? That’s all I need—I just didn’t want to translate your prototype to c++ only to figure out that what I want to do with it is impossible.

You really shouldn’t worry. Your membrane prototype is great and it was really one of the main reason’s I decided to work on it. At first I thought that doing something like this was completely impossible, but seeing you do it convinced me otherwise. Prototyping is also incredibly important as it prevents a lot of wasted time and bugs in the final prototype.

On another note, I think I figured out how to make my current membrane 3D—I just need to turn it into a prism and the subdivide it a couple of time (using the method described by Catmull-Clark) until I get a nice looking microbe. I tried it out in Blender and I think it looks fine. All I have to do know is actually figure out how that algorithm works…


On the top and bottom, you can see the 2D membrane shape I used. Here is a picture of it rendered with a cell looking shader:

That looks really good, I think if the microbes looked like that then it would be great.

I think it would be possible to start with a curve. The membrane is made of a mesh of points and you can fix the locations of any of them you like. For example you could fix the locations of all the ones around the equator without difficulty.

It should be possible to eliminate the “jump” yeah, if you don’t want to organelles to move then you can make the membrane movement extremely smooth.

Catmull-Clark sounds very similar to the algorithm I was using.

Hello, everyone! This is going to be my last post talking about my membrane prototype. I have been working on it for quite a while and I am fairly satisfied with the result. There are, however, some things I couldn’t get to work, even though I tried to. For example, I could not implement @tjwhale’s lunging behavior while at the same time eliminating the “jumps” you can see in the membrane. Nonetheless, I did end up rewriting most of my code to use tjwhale’s method as it provides a lot of flexibility and turned out to be a lot faster than mine was, so thanks for that.

One thing I did manage to implement that I thought was cool is phagocytosis. The player is able to pull on the cell membrane and stretch it out to cover an object, be it an enemy cell or a compound cloud, and when he lets go, the membrane smoothly glides back to its original shape.

So to reiterate, I finished my prototype—I am now able to create a smooth looking 3D membranes from the organelle positions—but my program only manages to create static membranes (they don’t deform at all as the cell moves forward or rotates). My question becomes, are you guys fine with this or not?

If you are, tomorrow I will begin porting this to the actual Thrive game. If you are not, I can continue trying to fix it and make it dynamic and maybe something will happen.

Here is a wireframe of one of my models:

And here is the respective positioning of the organelles:
http://forum.revolutionarygamesstudio.com/uploads/default/original/1X/2c5a76fb87afb63d2d3cd86cafca8900ea647d8f.png

That is awesome!

The way my prototype works is that it moves the organelles and that causes the membrane to move, have you tried that to get the membrane to move?

If you want any help or advice with it feel free to post your code. Happy to do anything I can to assist.

Woo, membranes! Great work!

For now this is absolutely fine. In the future it’ll need to be fixed, but at the moment we really just need something that looks more attractive and realistic than the arrangement of hexagons already in place. I assume your algorithm doesn’t handle collisions since you didn’t mention it? That might be a little more important than other environmental distortion.

Yeah, the things is that when I move the organelles, this happens:

The problem is that I average out the location of the points only when they are more than a set distance away from all the organelles. This can be fixed by making the organelles push really hard on the points, but then you can see jumps in the membrane which look too artificial. I could give you the code to play around with if you want. Hopefully you might find something I missed.

I was going to complain about the deformation going on in the center of the mesh (ie, the sharp point on the near and far flat sides), but then I realized that it would not matter at all, because we’ll be using fresnel shaders. Very smart, good job.

Making the membrane respond to organelle movement is not necessary right now, and would probably require something like what tjwhale did with repulsion terms etc. That would probably necessitate changing how we construct the cell’s outline from your bezier/slope trickery, but the good news is that we could keep what you’ve done to turn the outline into a 3D solid.

I think I’ve managed to make it a little better, see this video

What I did was simply change this function

def checkdistance(self):
    truelocation = self.pos + Vector(centre[0],centre[1],centre[2])
    for pt in controlpoints:
        distance_to_organelle = distance(truelocation, pt.pos)
        if distance_to_organelle <= 200:
            spherical = tospherical(self.pos)
            spherical.x += 30*math.exp(-distance_to_organelle/100)
            self.pos = tocartesian(spherical)

So basically the vertices flee from the organelles BUT when you are far from them flee slowly and when you are close to them flee faster. That way thy don’t suddenly jump. What was happening is that before I had it so if they were less than 100 they would add 30 to their radial coordinate. So they would be 102,101,100,130,129,128 etc and that was a bit horrible, I think this rather nicer they now flee at 30*exp(- distance/100) which decays nice a smoothly as they get further away.

Hope this is helpful! If there’s anything else I can do let me know,

Shouldn’t really be too hard to fix, either way. I originally put it there as a place-holder and was planning to code a triangulation algorithm later, but eventually I realized that since we aren’t going to put an actual texture there, we shouldn’t worry about texture warping.

Too late :stuck_out_tongue: Everything works now!

You are truly amazing! I took a look at your code and now everything works perfectly. I was already using an exponential function to control the movement, but no matter how much I tried I couldn’t make its look good. Interestingly enough, here is the function I used:
20*exp(- distance)
I was just one operation away from perfection :wink: Thanks again,

Here is an image of when the cell is moving upward fairly fast (the faster it goes, the more stretched out it becomes):


Keep in mind that it will be smoothed out even more once I make it three-dimensional. Eventually, I also plan to add motion blur to make it look even better.

No problem, very glad I could help. I think in general I am trying rebrand myself in this project from Theorist to Programming Assistant. The main thing I want to do is help people build stuff so this is really pleasing. I’m glad you’re making good progress. Let me know what I can do to help, whatever, whenever.

Time for another membrane update! For those of you not on slack, it might look that I (and the rest of the Thrive team) have disappeared for almost a month. Let me assure you that it isn’t so. Below is a picture of the current prototype of the membrane:


It has no organelles, is of one color, and has no collisions implemented—yet—but it is already so much better than the honeycombs we had previously.

I am looking forward to your critiques and suggestions (note that the jagged edges will be fixed once I turn on my sub-surf algorithm).

Edit: Fixed the jagged edges :slight_smile:

Awesome. *Applause.

Ah yes, here it is—the final, rendered version of the cell membrane. It looks done; however, the material is only semi-permanent. Rather than messing with shaders, I simply used a texture that I laid over the vertices. Some day I will get to fixing it, but if we want to get this into the next release, it will have to do. Plus, I’d say it looks good this way too, even if it’s not at all customizable.

Anyway, I am now going to take a break for a few weeks, but when I get back I will start working on the physics (note the three cells in the top right) and getting the organelles back inside the cells.

Cheers.

Edit: Silly me, forgot to upload the picture :blush:

3 Likes

Sorry for double posting, but I have done some more work on the membrane. I have created the following semi-transparent texture for the membrane. The one I had previously looked good, but you wouldn’t be able to see the organelles in it; plus, I think this actually makes it look more “celly”.

Comments?

Also, for those of you who don’t know this yet, I added physics, so you cannot go through a cell anymore. Basically, at this point I think that I am pretty much done with the membrane, and am ready to move on to some other part of the game.

3 Likes