Question about Rotation and RotationVelocity

All topics about ZGameEditor goes here.

Moderator: Moderators

Post Reply
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Question about Rotation and RotationVelocity

Post by Ats »

Hello. I have a question regarding Rotation and RotationVelocity.

I made a little example with some kind of ceiling fan that is rotated randomly right from the start, and then should rotate along its own Y axis:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="Model"/>
  </OnLoaded>
  <Content>
    <Model Name="Model">
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[CurrentModel.RotationVelocity.Y = 0.5;
CurrentModel.Rotation = rnd();]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnRender>
        <RenderMesh Mesh="Mesh"/>
      </OnRender>
    </Model>
    <Mesh Name="Mesh">
      <Producers>
        <MeshSphere/>
        <MeshBox Scale="5 0.1 0.5"/>
        <MeshCombine/>
        <MeshBox Scale="0.5 0.1 5"/>
        <MeshCombine/>
      </Producers>
    </Mesh>
  </Content>
</ZApplication>
Why RotationVelocity isn't making the model rotating on its own Y axis?
I also tried to avoid RotationVelocity and to use that in the model's OnUpdate:

Code: Select all

CurrentModel.Rotation.Y += 0.001;
But the result is the same.

How can I make the model to rotate on its own Y axis after a random rotation on all 3 axes right from the start?
I know I can do that using RanderTransformGroup, but the problem with that method is that the light with my shader don't take into account that transformation, so the shadow is rotating with the model...
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Question about Rotation and RotationVelocity

Post by Kjell »

Hi Ats,
Ats wrote: Sun Jul 24, 2022 7:39 pmWhy RotationVelocity isn't making the model rotating on its own Y axis?
This is because the default rotation axis order of a model is XYZ. For what you want to do you'd either need YXZ or YZX. Unfortunately you can't select the order of euler angles in ZGE, so the easiest solution is to orient your mesh differently and rotate over the X-axis instead .. here's a example.

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" LightPosition="0 1 0" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="Fan"/>
  </OnLoaded>
  <Content>
    <Model Name="Fan">
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[//

Fan.Rotation = rnd();
Fan.RotationVelocity.X = 0.5;]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnRender>
        <RenderMesh Mesh="FanMesh"/>
      </OnRender>
    </Model>
    <Mesh Name="FanMesh">
      <Producers>
        <MeshBox Scale="1 0.2 0.1"/>
        <MeshBox Scale="0.2 1 0.1"/>
        <MeshCombine/>
        <MeshTransform Rotation="0 0.25 0"/>
      </Producers>
    </Mesh>
  </Content>
</ZApplication>
Ats wrote: Sun Jul 24, 2022 7:39 pmI know I can do that using RanderTransformGroup, but the problem with that method is that the light with my shader don't take into account that transformation, so the shadow is rotating with the model...
Hmm .. perhaps the normalMatrix uniform doesn't get updated when using RenderTransform components? Maybe Ville can check up on this.

K
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Question about Rotation and RotationVelocity

Post by Ats »

Thanks Kjell, I'll try that :wink:
perhaps the normalMatrix uniform doesn't get updated when using RenderTransform components? Maybe Ville can check up on this.
I made a strip down example illustrating the difference:
  • The sphere on the left uses Model.Rotation
  • The one on the right uses RenderTransformGroup

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" GLBase="1" FileVersion="2">
  <OnLoaded>
    <ZExpression>
      <Expression>
<![CDATA[LightPosition[0][0,0] = 10000;
LightPosition[0][0,1] = 100;
LightPosition[0][0,2] = 10;]]>
      </Expression>
    </ZExpression>
    <SpawnModel Model="Model1" Position="-2 0 0"/>
    <SpawnModel Model="Model2" Position="2 0 0"/>
  </OnLoaded>
  <Content>
    <Model Name="Model1">
      <OnUpdate>
        <ZExpression Expression="CurrentModel.Rotation.Y += 0.005;"/>
      </OnUpdate>
      <OnRender>
        <UseMaterial Material="Material"/>
        <RenderMesh Mesh="Mesh"/>
      </OnRender>
    </Model>
    <Model Name="Model2">
      <OnSpawn>
        <ZExpression Expression="Transform.Rotate.Y = 0;"/>
      </OnSpawn>
      <OnUpdate>
        <ZExpression Expression="Transform.Rotate.Y += 0.005;"/>
      </OnUpdate>
      <OnRender>
        <UseMaterial Material="Material"/>
        <RenderTransformGroup Name="Transform">
          <Children>
            <RenderMesh Mesh="Mesh"/>
          </Children>
        </RenderTransformGroup>
      </OnRender>
    </Model>
    <Material Name="Material" Color="1 0.502 0.251 1" Shader="VertexDiffuseShader"/>
    <Shader Name="VertexDiffuseShader">
      <VertexShaderSource>
<![CDATA[//
#ifdef GL_ES
  precision mediump float;
#endif

uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

attribute vec4 position, color; // vertex position & color
attribute vec3 normal;   // vertex normal

varying vec3 N;
varying vec3 v;
varying vec4 v_Color;

void main(void)
{
  v = vec3(modelViewMatrix * position);
  N = normalize(normalMatrix * normal);
  v_Color = color;
  gl_Position = modelViewProjectionMatrix * position;
}]]>
      </VertexShaderSource>
      <FragmentShaderSource>
<![CDATA[//
#ifdef GL_ES
  precision mediump float;
#endif

varying vec3 N;
varying vec3 v;
varying vec4 v_Color;

uniform vec4 globalColor; // = Material.Color
uniform mat4 lightPosition;

void main (void)
{
  vec3 LPosition = vec3(lightPosition[0][0], lightPosition[0][1], lightPosition[0][2]);
  vec3 L = normalize(LPosition.xyz - v);
  vec4 Idiff = globalColor * max(dot(N, L), 0.0);

  gl_FragColor = v_Color * Idiff;
}]]>
      </FragmentShaderSource>
      <UniformVariables>
        <ShaderVariable VariableName="lightPosition" ValueArrayRef="LightPosition" ArrayKind="1"/>
      </UniformVariables>
    </Shader>
    <Mesh Name="Mesh">
      <Producers>
        <MeshSphere/>
        <MeshExpression VertexColors="255">
          <Expression>
<![CDATA[C.R = 1;
C.G = 1;
C.B = 1;]]>
          </Expression>
        </MeshExpression>
      </Producers>
    </Mesh>
    <Array Name="LightPosition" Type="5" SizeDim1="1"/>
  </Content>
</ZApplication>
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Question about Rotation and RotationVelocity

Post by Kjell »

Hi Ats,
Ats wrote: Mon Jul 25, 2022 10:49 amI made a strip down example illustrating the difference
Just checked your example using gDEBugger and indeed the normal matrix isn't updated / correct when using RenderTransform. So this is a bug in ZGE.

Image

K
User avatar
VilleK
Site Admin
Posts: 2274
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Re: Question about Rotation and RotationVelocity

Post by VilleK »

Thanks for the example. Indeed looks like a problem with the normal matrix just like Kjell said.

I've added a fix now. Please download latest version again.
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Question about Rotation and RotationVelocity

Post by Ats »

Wow, that was fast :shock:
Thanks, it's working perfectly now!
Post Reply