Go to QuArK Web Site
Bezier.pas
Updated 05 Apr 2018
Upper levels:
QuArK Information Base
4. The Source Code
4.5. File-by-file descriptions

 4.5.2. Bezier.pas

 [ Prev - Up - Next ] 

This file contains all the Delphi part of the code related to Quake 3's Quadratic Bezier patches.


 Index


 What is the math behind Quadratic Bezier patches?

Armin Rigo - 05 Apr 2018   [ Top ] 

These patches are defined with 9 (3x3) control points. Each control point has 5 coordinates: x,y,z (in 3D space) and s,t (texture coordinates).

In the map editor when you first insert a patch, its control points are ordered like this in the xy (top-down) view:

  6 7 8           c20 c21 c22
  3 4 5     or    c10 c11 c12
  0 1 2           c00 c01 c02

The patch is a parametric surface for two parameters u,v ranging between 0 and 1. Each for the 5 coordinates is computed using the formula described below.

A Quadratic Bezier Line is a curve defined by 3 control points and parametrized by a single variable u ranging between 0 and 1. If the 3 control points are p0, p1, p2 then the curve is parametrized by:

  f(u,p0,p1,p2)  =  p0 * (1-u)^2  +  p1 * 2u(1-u)  +  p2 * u^2

The Bezier surface is obtained by applying this formula for u and for v: if cji (i=0,1,2; j=0,1,2) are the 9 control points then

  g(u,v) = f(u, f(v,c00,c10,c20), f(v,c01,c11,c21), f(v,c02,c12,c22))

The formula can be seen as operating on each coordinate independently, or on all 5 coordinates at the same time (with vector sum and multiply in the real 5-dimensional vector space). In TBezier.BuildMeshCache the computations are done on the first 3 coordinates only because the texture coordinates are not cached.

The "speed vectors" 'dg/du' and 'dg/dv' are vectors that attach to each point (u,v) on the surface of the patch; they are the derivative of the function g. They tell "how fast" the point on the patch moves when u and v move. They are computed by extending as above the similar notion of speed on the Bezier curves:

  df/du (u,p0,p1,p2)  =  p0 * (-2)*(1-u)  +  p1 * (2-4u)  +  p2 * 2u

The vectors 'dg/du' and 'dg/dv' can also be used to compute (by cross product) a vector orthogonal to the surface at a given point.


 The Bezier patch objects

Armin Rigo - 05 Apr 2018   [ Top ] 

Try copying the text below and pasting it into QuArK. It will automatically be translated into an object -- in this case, a test Bezier patch.

QQRKSRC1
{
  test:b2 = {
    v = '0 0 0 0 0      64 0 0 64 0      128 0 0 128 0
         0 64 0 0 64    64 64 0 64 64    128 64 0 128 64
         0 128 0 0 128  64 128 0 64 128  128 128 0 128 128'
  }
}

The 'v' specific contains 5 values (x,y,z,s,t coordinates) for each control point, that is, 45 values in total.

This specific can be directly manipulated by Python code, but it's generally simpler to read and write the Python attribute "cp" (Control Points), which returns (resp. must be set to) a 3-tuple of 3-tuples of vectors (note: QuArK now supports "quilts", which mean that the dimension of the "cp" rectangular matrix can actually be any odd number.)

Vectors have been enhanced in this version of QuArK to allow them to hold all 5 coordinates of the control points. You create such a vector by passing 5 arguments to the function "quarkx.vect". The extra coordinates can be readen through the vector's "tex_s" and "tex_t" attributes, as well as through "tex" which directly returns a 2-tuple (tex_s, tex_t).



Copyright (c) 2022, GNU General Public License by The QuArK (Quake Army Knife) Community - https://quark.sourceforge.io/

 [ Prev - Top - Next ]