KPT Bryce Animation Help

KPT Bryce & Animation

The current version of Bryce does not have animation facilities. In order to render an animated sequence one has to create n-models, one for each frame, and change the camera position in the appropriate way in each model.

Changing the camera position by dragging via the mouse is a tedious and error-prone task. Bryce allows you to enter and change the camera coordinates,which are in a counter-intuitive coordinate system. Since we had to come up with the coordinates for a ca. 600 frame animation, I spent some time figuring out how to compute coordinates for intermediate frames, given a start and an end frame. This page explains what I found out and provides some code-snippets.

Each camera position has 5 "interesting" values: the x and y angle, and the xyz origin. With respect to the world coordinate system, the camera position is obtained by first applying the rotation and then applying the origin. This leads to the counter-intuitive behavior that one can not just change the angle and expect the camera to stay put in the world coordinate system. As a corollary, changing the camera origin without changing the angle might position the camera in unexpected positions in world coordinates, that is, in relationship to the whole model.

In order to compute intermediate coordinates, I do three things:

convert coordinates to world coordinates
take the camera angle and origin values of the start and end frame and convert them into world coordinates. Applying the transformations in the right sequence is crucial.
add delta
compute how the angle should change in each step and how far one wants to travel in each step (in world coordinates). This is done in a very simple fashion,dividing the distance into equal pieces, and moving the angle across the smallerangle in equal parts...
convert back to camera values
turn world coordinates for each frame back into camera angle and origin.this involves computing the new origin based on the given angles

Here are some code-snippets. They are all in Smalltalk. The hardest part forme to figure out was the correct transformation sequence, the rest of the code is not that exciting, and you should be able to implement the stuff below in any programming language, maybe even in some spreadsheet. The snippets assume a class called Transformation that represents 4x4 matrices and appropriate operations, as well as a Vector class for xyz values (constructed as x@y@z, e.g. 100@200@300 will generate a Vector instance with x=100, y=200, and z=300). The class all these snippets are in is called Bryce, all the methods are on the instance side.

The class Bryce has three instance variables, id (for identifying the frame), angle (the x and y angles), offset (the bryce camera origin).




toWorld: c

	"Return a vector in world coordinates, reflecting the

 	given camera coordinate"

	"(Bryce angle: 30@0 offset: 100@-210@237) toWorld: 0@0@0"



	^c * (Transformation translate: offset)

		* ((Transformation rotateX: angle x negated)

 		* (Transformation rotateY: angle y)).



toCamera: w

	"Return a vector in camera coordinates, reflecting the given

 	world coordinate"



	^w * ((Transformation rotateY: angle y negated)

 		* (Transformation rotateX: angle x))

		* (Transformation translate: offset negated).



to: end frames: n

	"Return n bryce objects, interpolating from self to b."

	"(Bryce id: 1000 angle: 4@-68 offset: 394@-123@10000)

 		to:(Bryce id: 2000 angle: 4@-68 offset: 394@-123@3000) frames: 10"



	| ws we delta deltaAngle |

	ws := self toWorld: 0@0@0. we := end toWorld: 0@0@0.

	delta := we - ws / n.

  	deltaAngle := self deltaAngle: self angle to: end angle frames: n.

	^(0 to: n-1) collect:[:i| | na w b bn |

		na := angle + (i * deltaAngle).  "new angle"

		w := ws + (delta ** i). "** multiplies vector by scalar"

		b := Bryce angle: na.

		bn := Bryce id: (self id + (i * 4)) "compute new id"

				angle: na offset: (b toCamera: w).

		bn

	].



newAngle: a

	"Return a new bryce object, keeping the camera at the same spot in world

	coordinates, but with a new angle, e.g.	(Bryce angle: 0@0 offset: 100@0@100) newAngle: -45@0

	should return: (Bryce angle: -45@0 offset: 100@-71@71)"



	| w b bn |

	w := self toWorld: 0@0@0.

	b := Bryce angle: a.

	bn := Bryce angle: a offset: (b toCamera: w).

	^bn

Here is an example, a 25 second excerpt (1MB) and scaled down version of Humanscapes, a video proposal by Joye Peters and myself:

humanscapes



updated 17 March 1996, © 1995, 1996 by Axel Kramer