Is the key delaying interpretation of a variable?


#1

I am modifying robot.rb in opengl’s sample directory,
the original robot turns, mine does not! snif…

The original example goes something like this
A display proc
display = Proc.new {

GL.Rotate($shoulder, 0.0, 0.0, 1.0);

}
a keyboard proc
keyboard = Proc.new {|key, x, y|
case (key)
when ‘s’[0]
$shoulder = ($shoulder + 5) % 360;
GLUT.PostRedisplay();

Then you tell glut the name of those procs
GLUT.DisplayFunc(display);
Glut.KeyboardFunc(keyboard);


The new program goes like this
def displaytree

traversetree

end

def traversetree
applytransform

end

def applytransform

GL.Rotate(*@rotation);
end

and in the initialization definition
@rotation = [$shoulder, 0.0, 0.0, 1.0]

GLUT.DisplayFunc(lambda{trunk.displaytree});
GLUT.KeyboardFunc(keyboard);

The first program rotates, the second one does not.
I am wondering if it has something to do with the 2nd method
estimating $shoulder in a different way from the first method?

@rotation is probably evaluated before creating the new object,
and after that this line is never accessed? So my display does not have

a $shoulder parameter to update?

scale=[2.0, 0.4, 1.0]
jointP=[-1, 0, 0]
translation=[$shoulderposx, $shoulderposy, 0.0]
rotation = [$shoulder, 0.0, 0.0, 1.0]
draw = Proc.new { GLUT.WireCube(1.0)}
upperarm = Node.new(scale, translation, jointP, rotation,&draw)

How can I keep the $shoulder parameter physically with all the other
parameters defining the shoulder definitions, and still have $shoulder
update with keyboard presses?


#2

To clarify the question

upperarm = Node.new(scale, translation, jointP, rotation,&draw)

is going to initialize
@rotation= [0,0,0,1]

How can I initialize it with
@rotation=[$shoulder, 0,0,1]

so when the gl and glut command comes along what it sees is
rotate([$shoulder, 0,0, 1])…
and not
rotate([0,0,0,1])

How do I prevent ruby from interpreting $shoulder so glut can have a go
at it?

How do I delay the interpretation of this parameter?


#3

anne001 wrote:

so when the gl and glut command comes along what it sees is
rotate([$shoulder, 0,0, 1])…
and not
rotate([0,0,0,1])

How do I prevent ruby from interpreting $shoulder so glut can have a go
at it?

How do I delay the interpretation of this parameter?

Maybe something like this… but dont know whether it is going to be
helpful:

a=nil

l=lambda{
[a,0,0,0]
}

a=5

p l[]

lopex


#4

“anne001” removed_email_address@domain.invalid writes:

so when the gl and glut command comes along what it sees is
rotate([$shoulder, 0,0, 1])…
and not
rotate([0,0,0,1])

How do I prevent ruby from interpreting $shoulder so glut can have a go
at it?

How do I delay the interpretation of this parameter?

I’d question how your code is structured. You’re correct in that once
you do:

@rotation = [$shoulder, 0, 0, 1]

…changing $shoulder:

$shoulder = 90

…won’t change @rotation[0].

A few options come to mind:

  1. Provide funky angle accessors that modify the @rotation array
    instead:

class Node
def angle
@rotation[0]
end
def angle= val
@rotation[0] = val
end
end

upperarm = Node.new(…)
upperarm.angle = 90

  1. Store the rotation angle and axis separately:

class Node
def initialize(angle, axis, …)
@angle = angle
@axis = axis

end
attr_accessor :angle, :axis

def draw
  ...
  rotate(@angle, *@axis)
  ...
end

end

  1. If you insist on using a global, use it in place of “@angle” in 2.

class Node
def initialize(axis, …)
@axis = axis

end
attr_accessor :axis

def draw
  ...
  rotate($shoulder, *@axis)
  ...
end

end

HTH.


#5

Thank you so much for your response. I had tried Marcin’s suggestion,
but
got error messages.

I have been wondering what to do, and then I saw your suggestion from
last
week, and suddenly what you were saying clicked!

If you insist on using a global
That’s it! In the original program, $shoulder is a global so various
parts of the
program can access it. It holds the memory of the system.

Having rewritten the program an OOP way, this is no longer necessary.
The object holds the memory of the system! So I changed the keyboard
proc to say

keyboard = Proc.new {|key, x, y|
case (key)
when ‘s’[0]
upperarm.rotation[0] = (upperarm.rotation[0] + 5) % 360;
GLUT.PostRedisplay();

and now it all works fine. I hadn’t really understood what the keyboard
proc was doing!

Thank you!!! I can move on again! wonderful.