[WIP]Interactive Grass

Post » Sat Jan 15, 2011 7:08 am

I have tried, however being really bad at math I hit the books and studied hard but I still can't apply my current knowledge in programming terms so I come here asking for assistance.

The idea is to make the grass move aside as you move through it and then return to it's normal blowing in the wind.

Altering the Ingame.fx to this, note that I did not really do much I just collected pieces of information from Peachykeen & Liztail and put this together:

GrassVertOut GrassVS( GrassVertIn IN, float4 posv : POSITION0 ) {
GrassVertOut OUT;

OUT.texcoords = IN.texcoords;

//Animate grass
float proxydist = distance(posv.xy, EyePos.xy);
if (proxydist < 30)
{
//Insert fun Trigonometry! (Push verts away from camera)
}


float4 worldpos = mul(IN.pos, world);

float height = clamp(IN.pos.z, 0, 100) / 100;

float2 wind = WindVec * 2.5 + 0.25;

float2 pos_ticks1 = worldpos.xy / 1000 + ticks;
float2 pos_ticks2 = worldpos.xy / 750 + ticks * 2;
float2 pos_ticks3 = worldpos.xy / 500 + ticks * 3;
float2 pos_ticks4 = worldpos.xy / 200 + ticks * 4;

worldpos.xy += ( sin(pos_ticks1) + cos(pos_ticks2) + sin(pos_ticks3) + cos(pos_ticks4) ) * height * wind * 10;

//Define % to Fog
float dist = length(worldpos.xyz - EyePos.xyz);
OUT.fog = saturate( (FogRange - dist) / (FogRange-FogStart) );

//Define % to Blend
OUT.blend = saturate( (BlendEnd - dist) / (BlendEnd-BlendStart) );

//Projection
OUT.pos = mul(worldpos, view);
OUT.pos = mul(OUT.pos, proj);

//Texture Projection
OUT.screenpos = mul( worldpos, TexProj );

//Lighting
OUT.color = (SunCol * 0.25) + SunAmb;

return OUT;
}


This is what Liztail has to say about it:
Hi Peter,

I think the main problem with what you're trying to do is that the EyePos constant contains the position of the camera, not the player. So while this might kinda work in first person view, it would look really weird in 3rd person view because the invisible camera would be rustling the grass somewhere where there isn't anything. You might want to try to ask the people working on MGE and MSE whether there's some way that they can get you the actual position of the player's feet.

As far as the math, I think you'd just need to create a vector that goes from the center of the player's feet to the worldpos of the current vertex using subtraction, and then push the vertex in that direction by an amount that varies with distance. I can't remember what posv is, but the local position of the vertex is stored in IN.pos. It's not in world coordinates until it's multiplied by world in the next line to create the worldpos vector. To make it vary with distance, you would then calculate the length of that vector before normalizing it. Then you'd use a mathematical function that starts at one when the input is zero and goes down to zero when the input is 30. A linear function would probably be fine. At this point, multiplying the normalized vetor with this scaling factor so that the vertices that are close would cause them to get pushed one unit away from the player's feet while the ones that are far wouldn't get moved at all. You could then multiply that result by some constant scaling factor like 20 so that the vertices close to the player move by 20 units instead of one unit, which would have a more visible result.

Good luck,
--LizTail


I still have no idea what variable to use. I know that Eyepos works as a temporary hack as long as you are in 1st person... It's sad that not even the camera position is really of any use.

Player position is direly needed. I recall that Timeslip had an old mod for Mw that got the player position from MGE for distant land. Later the function was made faster by moving it to MGE completely. It should still be in use, perhaps internal to MGE code. This is my next step I guess, trying to delve into MGE code...

Also looking at liztails explanation now, I can understand more then the first time I looked at it. I will continue trying until something comes out of this =)
User avatar
Marie
 
Posts: 3405
Joined: Thu Jun 29, 2006 12:05 am

Post » Sat Jan 15, 2011 2:17 am

Wow, sounds like an amazing idea. Good luck! I will really have my fingers crossed for this one.
User avatar
Robert
 
Posts: 3394
Joined: Sun Sep 02, 2007 5:58 am

Post » Sat Jan 15, 2011 7:02 am

Man, I wish I could help you. I know exactly what you're saying but I'm not familiar with that script language. :(
User avatar
Blaine
 
Posts: 3456
Joined: Wed May 16, 2007 4:24 pm

Post » Sat Jan 15, 2011 12:02 am

Man, I wish I could help you. I know exactly what you're saying but I'm not familiar with that script language. :(

Dude... I wish I was o_O

I'm having some kind of luck raging through MGE code atm. But mostly in understanding how it works, not finding anything useful yet.
User avatar
Richard
 
Posts: 3371
Joined: Sat Oct 13, 2007 2:50 pm

Post » Sat Jan 15, 2011 1:35 am

That's a great idea! :ooo:

Would this work on NPCs traveling in Grass, too? Is there any way to find where a mesh collides with the landscape (i.e., the feet)?
User avatar
Sakura Haruno
 
Posts: 3446
Joined: Sat Aug 26, 2006 7:23 pm

Post » Sat Jan 15, 2011 7:02 am

That's a great idea! :ooo:

Would this work on NPCs traveling in Grass, too? Is there any way to find where a mesh collides with the landscape (i.e., the feet)?

Not that I know of. This would be a player feature only. Unless somebody chimes in with the knowledge of how to scan a cell for all NPCs and get their position.. It would probably be very heavy on fps...
User avatar
Nikki Hype
 
Posts: 3429
Joined: Mon Jan 01, 2007 12:38 pm

Post » Sat Jan 15, 2011 3:23 am

Couldn't you use MWSE to check the cell references for NPCs and then use ref-GetPos? You could use GetAngle to determine facing, too.

I know it's possible to do--probably not that hard. I was working on a soultrap mod for a little while that scanned all the creatures in a cell to check if they had been soultrapped. Unfortunately, getspelleffect->soultrap is bugged :/
User avatar
Clea Jamerson
 
Posts: 3376
Joined: Tue Jun 20, 2006 3:23 pm

Post » Sat Jan 15, 2011 2:32 am

Couldn't you use MWSE to check the cell references for NPCs and then use ref-GetPos? You could use GetAngle to determine facing, too.

I know it's possible to do--probably not that hard. I was working on a soultrap mod for a little while that scanned all the creatures in a cell to check if they had been soultrapped. Unfortunately, getspelleffect->soultrap is bugged :/

Might be possible. I don't know how Ingame.fx of MGE interacts with MWSE. But that does not sound like a very bad idea at all.

Eventually this things would stretch to any plant using the "grass" tag of MGE which would mean any plant would do this. All would not look good tho, I guess.
User avatar
Tania Bunic
 
Posts: 3392
Joined: Sun Jun 18, 2006 9:26 am

Post » Sat Jan 15, 2011 8:09 am

;use something to get the script running--it should be a globalifx ( run )	ifx ( creaRef )		setx creaRef to xNextRef creaRef		set DoOnce to 0	else		setx creaRef to xFirstNPC	endif	if ( creaRef == 0 )		set run to 0		return;if this happens, there are no NPCs in the cell, or we've gone through the list of NPCs.	endif	setx temp to creaRef->xRefType	if ( temp != ???? );if any modder knows the reference # for an NPC, please tell me. That's the number needed in this slot. To be honest, I'm not sure this count is needed		Return			;if omitted, creatures and NPCs would both be included for the scripts count of actors	endif   ;;in this section, put as many storage blocks as needed to keep track on NPCs in a cell. Ten would probably be fine.	if ( store1 == 0 )		set store1 to creaRef	else		if ( store2 == 0 )			set store2 to creaRef		else;;after all storage blocks needed			return		endif	endif	if ( store1 > 0 )		set ref1x to store1->GetPos x		set ref1y to store1->GetPos y		set ref1z to store1->GetPos z		set ref1ang to store1->GetAngle z	endif;repeat for other stored actors, this will give x,y,z and facing for actors


That's as much of the code as I can work out... I'm not even sure it'd even work (if finished, that is) I'm a real scrub when it comes to MWSE, but I think it wouldn't be hard for someone with a little more knowledge of MWSE to fix up that base and make it work for you.
User avatar
Stryke Force
 
Posts: 3393
Joined: Fri Oct 05, 2007 6:20 am

Post » Fri Jan 14, 2011 10:55 pm

Thanks a lot =)

In other words, you would then pass on the result of ref1x, ref1y, ref1z and up into the Ingame.fx file and then I would need to convert it to some kind of world coordinates that the shader understands.

Isn't GetPos slow tho? I guess it would essentially run every frame for every NPC in the cell... sounds like a load.
User avatar
Rachael
 
Posts: 3412
Joined: Sat Feb 17, 2007 2:10 pm

Post » Sat Jan 15, 2011 11:46 am

Thanks a lot =)

In other words, you would then pass on the result of ref1x, ref1y, ref1z and up into the Ingame.fx file and then I would need to convert it to some kind of world coordinates that the shader understands.

Isn't GetPos slow tho? I guess it would essentially run every frame for every NPC in the cell... sounds like a load.


That is the problem :/
User avatar
Sheila Reyes
 
Posts: 3386
Joined: Thu Dec 28, 2006 7:40 am

Post » Sat Jan 15, 2011 8:45 am

That is the problem :/

Thing is. The game has to know where NPCs are in the memorymap somewhere... Like it should have variables it fills up all by itself to keep track, it would be best to find that, so MW would not get to much load.

Also doing the interactive grass for NPCs as well might need some change to how we think about the interaction... like.. what happens when two NPCs get within distance.

Hmm..
User avatar
Eileen Müller
 
Posts: 3366
Joined: Fri Apr 13, 2007 9:06 am

Post » Sat Jan 15, 2011 10:05 am

I know I'm going into the uninviting world of ordinary Morrowind scripting now, but could http://www.uesp.net/wiki/Tes3Mod:GetCollidingActor be helpful at all?
Maybe you could combine it with GetAngle, I mean you only need to know when they collide with the grass and the angle, not necassarily the position, don't you? :shrug:

edit: Thought tbh I'm not sure if an fps drop would be caused by having it on so many objects.
User avatar
Kortknee Bell
 
Posts: 3345
Joined: Tue Jan 30, 2007 5:05 pm

Post » Sat Jan 15, 2011 11:10 am

I know I'm going into the uninviting world of ordinary Morrowind scripting now, but could http://www.uesp.net/wiki/Tes3Mod:GetCollidingActor be helpful at all?
Maybe you could combine it with GetAngle, I mean you only need to know when they collide with the grass and the angle, not necassarily the position, don't you? :shrug:

edit: Thought tbh I'm not sure if an fps drop would be caused by having it on so many objects.

While what you say is true about not needing position but that collision would work as well... here are my thoughts:
Some issues:
1, Can't really attach getcolliding actor to MGE rendered meshes, this would move us back to MW's static grass without it blowing in the wind. (At best it would be animated grass). And that would mean that vertex shader would not work on it so it would render this whole thing useless.
2, You would only get collision which would be more inaccurate then position of character to the distance of the grass meshes since that is tweakable through variables
3, As you say yourself, probably that is even more FPS consuming. It's much less so if the only thing you have to look for is distance to npc then collsion, collision being far more complex.

Thank you for the ideas tho =)
User avatar
Monika Fiolek
 
Posts: 3472
Joined: Tue Jun 20, 2006 6:57 pm

Post » Fri Jan 14, 2011 10:54 pm

So you can't attach getcollidingactor with MGE rendered things, but you can attach position scripts, why's this? :huh:
It isn't necassary for the mesh to have collision as long as the actor has collision, is it?

Though I said it might cause an fps impact, I'm not sure it'd be as great as using GetPos.
Lava detects collision, and yet they don't cause any fps drop at all. x50 and they probably will, but you'll get that with your position method anyway.
It would be less flexible, but very accurate (larger things will activate more than one grass automatically for example), and detecting collision is more fps friendly than GetPos in most cases.
I thought this was how most games do this anyway, through collision?

About Morrowind using a variable to get actor position, isn't that what GetPos uses?
Attaching a script that tracks wherever a load of NPCs go every frame is gonna cause an fps lag, maybe the function could be optimized or something though. :shrug:
User avatar
Khamaji Taylor
 
Posts: 3437
Joined: Sun Jul 29, 2007 6:15 am

Post » Sat Jan 15, 2011 2:02 am

So you can't attach Morrowind scripts with MGE rendered things, but you can attach MWSE scripts, why's this? :huh:

Though I said it might cause an fps impact, I'm not sure it'd be as great as using GetPos.
Lava detects collision, and yet they don't cause any fps drop at all. x50 and they probably will, but you'll get that with your position method anyway.
It would be less flexible, but very accurate (larger things will activate more than one grass automatically for example), and detecting collision is more fps friendly than GetPos in most cases.
I thought this was how most games do this anyway, through collision?

About Morrowind using a variable to get actor position, isn't that what GetPos uses?
Attaching a script that tracks wherever something goes every frame is gonna cause an fps lag, maybe the function could be optimized or something though. :shrug:

You can pass on variables to MGE of things that ar inside of the game through scripts. The MGE rendered grass is not in game however the player is. So you can get the players position but not any collision since the grass is made by MGE. Also comparing position to distance is easy because both exist in MGE and morrowind. MGE does not understand MW's collision.

I still do think both GetPos and GetColliding actor are both slow. I take neither of those sides atm. I mostly hope for having an MGE variable I can use so I don't need any MW or MWSE script, solving it fully internally to MGE ought to be the fastest. I would hate to strain the CPU with more mw code then it already has to cope with.

Oh but. You would collide with the mesh/collision mesh and not with the alpha enabled blades of grass now would you not?
User avatar
Philip Rua
 
Posts: 3348
Joined: Sun May 06, 2007 11:53 am

Post » Sat Jan 15, 2011 7:28 am

I'm not sure, lava has no collision yet it can detect when the player is on it through HurtStandingActor, I think GetColliding functions work the same way.
I'm sure lava detects collision, because you can go above or below lava and not be hurt. It knows when you're touching the lava, so it's collision, isn't it?
Plus Bounding Boxes are the things which collide.

Thanks for clearing that up, I thought MGE could understand collision... I know next to nothing about MGE.

I'd still prefer collision to position though. :D
User avatar
Neko Jenny
 
Posts: 3409
Joined: Thu Jun 22, 2006 4:29 am

Post » Sat Jan 15, 2011 10:31 am

I'm going to assume the code is wrong somewhere because it isn't working. This should in theory work to get it to work in 1st person. In 3rd person it would all fall apart, obviously.

GrassVertOut GrassVS( GrassVertIn IN, float4 posv : POSITION0 ) {
GrassVertOut OUT;

OUT.texcoords = IN.texcoords;

//Animate grass
float proxydist = distance(posv.xy, EyePos.xy);
if (proxydist < 30)
{
float3 worldpos = mul(IN.pos, world);
float3 shift = worldpos - EyePos;
shift /= 10;
worldpos += shift;
}
else
{

float4 worldpos = mul(IN.pos, world);

float height = clamp(IN.pos.z, 0, 100) / 100;

float2 wind = WindVec * 2.5 + 0.25;

float2 pos_ticks1 = worldpos.xy / 1000 + ticks;
float2 pos_ticks2 = worldpos.xy / 750 + ticks * 2;
float2 pos_ticks3 = worldpos.xy / 500 + ticks * 3;
float2 pos_ticks4 = worldpos.xy / 200 + ticks * 4;

worldpos.xy += ( sin(pos_ticks1) + cos(pos_ticks2) + sin(pos_ticks3) + cos(pos_ticks4) ) * height * wind * 10;

//Define % to Fog
float dist = length(worldpos.xyz - EyePos.xyz);
OUT.fog = saturate( (FogRange - dist) / (FogRange-FogStart) );

//Define % to Blend
OUT.blend = saturate( (BlendEnd - dist) / (BlendEnd-BlendStart) );

//Projection
OUT.pos = mul(worldpos, view);
OUT.pos = mul(OUT.pos, proj);

//Texture Projection
OUT.screenpos = mul( worldpos, TexProj );

//Lighting
OUT.color = (SunCol * 0.25) + SunAmb;
}

return OUT;
}
GrassVertOut GrassInstVS( StatInstVertIn IN, float4 posv : POSITION0 ) {
GrassVertOut OUT;

//Pack instance transform
float4x4 worldmat = float4x4(IN.m1, IN.m2, IN.m3, IN.m4);

OUT.texcoords = IN.texcoords;

//Define % to Fog
float4 worldpos = mul(IN.pos, worldmat);
float dist = length(worldpos.xyz - EyePos.xyz);
OUT.fog = saturate( (FogRange - dist ) / (FogRange-FogStart) );
OUT.blend = 1 - (saturate( (GrassDist-dist) / (GrassDist/5) ));
OUT.blend += 0.4;
OUT.screenpos = 0;

//Animate grass
float proxydist = distance(posv.xy, EyePos.xy);
if (proxydist < 30)
{
float3 worldpos = mul(IN.pos, world);
float3 shift = worldpos - EyePos;
shift /= 10;
worldpos += shift;
}
else
{

float height = clamp(IN.pos.z, 0, 100) / 100;

float2 wind = WindVec / 6;

float2 pos_ticks1 = worldpos.xy / 1000 + ticks;
float2 pos_ticks2 = worldpos.xy / 750 + ticks * 2;
float2 pos_ticks3 = worldpos.xy / 500 + ticks * 3;
float2 pos_ticks4 = worldpos.xy / 250 + ticks * 4;

worldpos.xy += ( sin(pos_ticks1) + cos(pos_ticks2) + sin(pos_ticks3) + cos(pos_ticks4) ) * height * wind * 10;

//Projection
OUT.pos = mul(worldpos, view);
OUT.pos = mul(OUT.pos, proj);

//Lighting
OUT.color = (SunCol * 0.25) + SunAmb;

}
return OUT;
}


FYI, the GrassInstVS is for instancing of grass in the back. It should be unnecessary to add the code for interactive grass but for testing puspuse I did it here.

Thanks Peachykeen for some additional code.
User avatar
Neko Jenny
 
Posts: 3409
Joined: Thu Jun 22, 2006 4:29 am

Post » Fri Jan 14, 2011 10:12 pm

I'm not sure, lava has no collision yet it can detect when the player is on it through HurtStandingActor, I think GetColliding functions work the same way.
I'm sure lava detects collision, because you can go above or below lava and not be hurt. It knows when you're touching the lava, so it's collision, isn't it?
Plus Bounding Boxes are the things which collide.

Lava simply has a box under it that does have collision, you're standing on it so "GetStandingActor" and "HurtStandingActor" work for it :shrug:


http://www.uesp.net/wiki/Tes3Mod%3a%50CGet3rdPerson anyone?
User avatar
Rinceoir
 
Posts: 3407
Joined: Thu Jun 29, 2006 1:54 am

Post » Fri Jan 14, 2011 11:07 pm

Lava simply has a box under it that does have collision, you're standing on it so "GetStandingActor" and "HurtStandingActor" work for it :shrug:


http://www.uesp.net/wiki/Tes3Mod%3a%50CGet3rdPerson anyone?

But that would only be needed to turn off the grass interaction script on 3rd person camera. Which would look weird and inconsistent.

Thanks for clarifying the way lava works =)
User avatar
Jade
 
Posts: 3520
Joined: Mon Jul 10, 2006 6:42 am

Post » Sat Jan 15, 2011 12:15 am

Bump for the early crowd. I'm right now trying to figure out why my edits do not yield any results so far, I'm right now trying to debug it by adding some extreme behaviours and maybe even some temporary color changes when you get close to a mesh so it "activates" for it to be modified.
User avatar
Yvonne Gruening
 
Posts: 3503
Joined: Mon Apr 23, 2007 7:31 pm

Post » Sat Jan 15, 2011 1:35 pm

Bump for the early crowd. I'm right now trying to figure out why my edits do not yield any results so far, I'm right now trying to debug it by adding some extreme behaviours and maybe even some temporary color changes when you get close to a mesh so it "activates" for it to be modified.



Very cool, I hope it all works out, because seriously, the first game I remember having this effect was Knights of the Old Republic, and I remember thinking how incredible it was, to be honest, its still one of the coolest effects in a game, I'd love to see it in morrowind! :P :D
User avatar
Breanna Van Dijk
 
Posts: 3384
Joined: Mon Mar 12, 2007 2:18 pm

Post » Sat Jan 15, 2011 9:25 am

Very cool, I hope it all works out, because seriously, the first game I remember having this effect was Knights of the Old Republic, and I remember thinking how incredible it was, to be honest, its still one of the coolest effects in a game, I'd love to see it in morrowind! :P :D

I am very excited about it too.

@C_Mireneye
I want to help but I never look that side of the codes. Are you editing ingame.fx only or MGE's c codes too?
User avatar
Amanda savory
 
Posts: 3332
Joined: Mon Nov 27, 2006 10:37 am

Post » Fri Jan 14, 2011 11:43 pm

I am very excited about it too.

@C_Mireneye
I want to help but I never look that side of the codes. Are you editing ingame.fx only or MGE's c codes too?

ATM only ingame.fx

I have been looking inside mges code to try to find out if MGe knnows player position for distant land, it should know since I doubt it can accordingly calculate the 3rd person cam otherwise.
User avatar
Your Mum
 
Posts: 3434
Joined: Sun Jun 25, 2006 6:23 pm

Post » Sat Jan 15, 2011 4:53 am

Well I'm officially stuck with this until someone comes a long and gives me something to work with. I have some things to test based on the words of PK tho.

What I need is actor position, x,y,z, and not the 1st person camera of the player and not the 3rd person either. Simply put, the x,y,z of the model.

I think it should be traceable if somebody use the "placeat" command and track/look for those coordinates for the actor you just placed, that way maybe we could find a way to retrieve the data.

Some things I'm sure about:
*The original placement is saved in the ESM/ESPs
*The placement is offset by save games so saves share this information.
*What we need is the placement in the memory-map. Essentially MW needs to know this it's just a matter of retrieving the data.
User avatar
no_excuse
 
Posts: 3380
Joined: Sun Jul 16, 2006 3:56 am

Next

Return to III - Morrowind