Rainy Mountains

Ben Young, cs184-fx

-- Update 5/20/03 4:37 PM: Coefficient of friction between water and landscape changed from .25 to .05. Water dynamics greatly improved. Available here. --

Introduction

Rainy Mountains is an (almost) real-time random landscape and particle-based water simulator.

Random terrain is generated using an enhanced version the triangle subdivision method discussed in class, with a level of detail algorithm: closer triangles are subdivided more to maintain an approximately even triangle screen size. Triangles are not subdivided until they are visible and within range. When they go out of view / range, they are cached, but not rendered. Triangles on the border of two subdivision levels are divided on the fly into 2 or 3 triangles as necessary to achieve mesh alignment. Vertices are colored based on height. Vertex normals are based on the sum of the normals of the connecting triangles. Triangles are Gouraud shaded by GL.

Water is simulated with a particle system. I was unable to process enough particles in real time to even consider skinning the water in a polygon mesh. Particles are rendered as translucent unshaded spheres, with color proportional to velocity. Particles collide with terrain according to standard mechanics models. Collisions are partially elastic: velocity normal to the surface is reversed and scaled by an elasticity constant, and velocity parallel to the surface is scaled by a function of friction and normal force.

Particle interactions are simplified by storing each particle in two 3-dimensional grids of hash tables. The hash tables themselves are hashed, so they can be created on the fly as particles enter their grid space, for the first time and referenced in constant time. The two grids are offset 50% in each direction from each other, so that every particle is no more than 50% away from the center of one grid-cube. In for each particle in every time-step, each the current velocity of each particle is adjusted based on gravity, surface collisions, and electrostatic forces f from all particles in the grid-cube of which the center is closest to the particle. Electrostatic forces between two particles given by the formula:

      max (f, a × (1 - ((d ÷ b)2) ÷ ((d ÷ b)4)

where

  • f   is the maximum force allowed (to prevent particles that are too close from flying away sporadically)
  • a  is the relatives strength of the force
  • b  is the stable distance between the two particles
  • d  is the current distance between the two particles

Instructions

Download and unzip landscape.zip and run on any OpenGL enabled Windows computer. C++ source code is available here and should compile on any computer with GLUT installed (there is no make file, as the lab workstations are far too slow to run the simulation. Landscape.cpp contains the main() function). Frame rates are almost tolerable on my P3 1.13 GHz laptop with a Geforce2 MX video adapter for about 100 particles. Run landscape.exe to start the simulation. The window opens at 640x480. A new landscape is generated each time the program is run.

The mouse is used to control the camera view direction. The keyboard is used to move the camera. If the camera is near the ground, it will hover at a constant height above the ground while the user moves horizontally. There is nothing to prevent the user from moving the camera below the ground, however.

Keys

  • W - move forward
  • S - move backward
  • A - move left
  • D - move right
  • Q - move down
  • E - move up
  • R - move camera back to start

  • SPACE - while pressed, adds 32 particles of rain to the center of the terrain (near the start point) (use judiciously)
  • F - toggle wire frame mode
  • L - lock the terrain mesh so that it does not adjust triangle subdivisions while the camera moves around
  • ESC - quit
  • Issues

    • There are glitches in the painting order of the mountains. I believe this is an issue with OpenGL, and I have not figured out how to solve it. (I'm using the OpenGL z-buffer.)
    • The mouse causes the camera to rotate around the world's X and Z axes, so when the user turns around, the mouse's vertical axis is inverted. (Just didn't have time).
    • More than 100 particles is extremely slow. A possible improvement would be to recalculate only a fraction of the particles' velocities at each time step.
    • The water, of course, would look better if it were skinned and calculated with more particles. Unfortunately, my implementation is too slow. Perhaps it can be optimized (the implementation makes use of many interacting classes and many function calls, and perhaps data copying could be reduced).
    • Collision elasticity, particle bond strength, the coefficient of friction, particle size, etc. cannot be specified without recompiling the program. These items should be user specifiable.

    Contract

    Available here.

    Deliverable 2 Web site

    Available here.

    Revised Point Breakdown

    • 35% Modeling
    • 25% Animation
    • 25% Rendering
    • 15% Interface

    My modeling seems to have come out a bit better than my animation, but I don't suppose it really matters. Whatever seems most appropriate is fine.

    Images