Page 1 of 1

Question about Rotation and RotationVelocity

Posted: Sun Jul 24, 2022 7:39 pm
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...

Re: Question about Rotation and RotationVelocity

Posted: Mon Jul 25, 2022 10:10 am
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

Re: Question about Rotation and RotationVelocity

Posted: Mon Jul 25, 2022 10:49 am
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>

Re: Question about Rotation and RotationVelocity

Posted: Mon Jul 25, 2022 11:05 am
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

Re: Question about Rotation and RotationVelocity

Posted: Mon Jul 25, 2022 11:12 am
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.

Re: Question about Rotation and RotationVelocity

Posted: Mon Jul 25, 2022 11:19 am
by Ats
Wow, that was fast :shock:
Thanks, it's working perfectly now!