primitive-data

Description

Primitive data (pdata for short) is fluxus' name for data which comprises primitives. In polygon primitives this means the vertex information, in particle primitives it corresponds to the particle information, in NURBS primitives it's the control vertices. Access to pdata gives you the ability to use primitives which are otherwise not very interesting, and deform and shape other primitives to give much more detailed models and animations. You can also add your own pdata, which is treated exactly like the built in types. Primitive data is named by type strings, the names of which depend on the sort of primitive. All pdata commands operate on the currently grabbed primitive.

Example

 ; a function to deform the points of an object
 (define (deform n)
     (pdata-set! "p" n (vadd  (pdata-ref "p" n)                ; the original point, plus
         (vmul (vector (flxrnd) (flxrnd) (flxrnd)) 0.1)))     ; a small random vector
     (if (zero? n)
         0
         (deform (- n 1))))
     
 (hint-unlit) ; set some render settings to
 (hint-wire)  ; make things easier to see
 (line-width 4)
 (define myobj (build-sphere 10 10)) ; make a sphere
 (grab myobj)
 (deform (pdata-size)) ; deform it
 (ungrab)

(pdata-ref type-string index-number)

Returns value-vector/colour/matrix/number

Returns the corresponding pdata element.

Example

 (pdata-ref "p" 1)

(pdata-set! type-string index-number value-vector/colour/matrix/number)

Returns void

Writes to the corresponding pdata element.

Example

 (pdata-set! "p" 1 (vector 0 100 0))

(pdata-add name-string type-string)

Returns void

Adds a new user pdata array. Type is one of "v":vector, "c":colour, "f":float or "m":matrix.

Example

 (pdata-add "mydata" "v")
 (pdata-set "mydata" 0 (vector 1 2 3))

(pdata-exists? name-string)

Returns void

Returns true if the pdata array exists on the primitive

Example

 (with-primitive (build-cube)
   (when (pdata-exists? "p") 
     (display "we have positions!") (newline))
   (pdata-add "myarray" "v")
   (when (pdata-exists? "myarray") 
     (display "we have myarray!") (newline)))

(pdata-names)

Returns void

Returns a list of the names of the pdata arrays for this primitive. t -> texture p -> position c -> color

Example

 (with-primitive (build-cube)
     (display (pdata-names)) (newline))

(pdata-op funcname-string pdataname-string operator)

Returns void

This is an experimental feature allowing you to do operations on pdata very quickly, for instance adding element for element one array of pdata to another. You can implement this in Scheme as a loop over each element, but this is slow as the interpreter is doing all the work. It's much faster if you can use a pdata-op as the same operation will only be one Scheme call.

Example

 (clear)
 (define t (build-torus 1 4 10 10))
 
 (with-primitive t
     (pdata-op "+" "p" (vector 1 0 0))  ; add a vector to all the pdata vectors
     (pdata-op "+" "p" "n")  ; add two pdata vectors element for element
     (pdata-op "*" "n" (vector -1 -1 -1)) ;  multiply a vector to all the pdata vectors
     (pdata-op "*" "n" "p")  ; multiply two pdata vectors element for element
     (let ((pos (pdata-op "closest" "p" (vector 100 0 0)))) ;  returns position of the closest vertex to this point
         (with-state ; draw a sphere there
             (translate pos)
             (scale (vector 0.1 0.1 0.1))
             (build-sphere 5 5)))
     ; can't think of a good example for these...
     ;(pdata-op "sin" "mydata" "myotherdata")  ; sine of one float pdata to another
     ;(pdata-op "cos" "mydata" "myotherdata")  ; cosine of one float pdata to another
     )
 
 ; most common example of pdata op is for particles
 (define p (with-state
     (hint-points)
     (point-width 10)
     (build-particles 100)))
 
 (with-primitive p
     (pdata-add "vel" "v") ; add a velocity vector
     (pdata-map!
         (lambda (vel)
             (srndvec)) ; set random velocities
         "vel")
     (pdata-map!
         (lambda (c)
             (rndvec)) ; set random colours
         "c"))
 
 (every-frame (with-primitive p
     (pdata-op "+" "p" "vel"))) 

(pdata-copy pdatafrom-string pdatato-string)

Returns void

Copies the contents of one pdata array to another. Arrays must match types.

Example

 (pdata-copy "p" "mydata") ; copy the vertex positions to a user array

(pdata-size)

Returns count-number

Returns the size of the pdata arrays (they must all be the same). This is mainly used for iterating over the arrays.

Example

 (define (mashup n)
     (pdata-set "p" n (vector (flxrnd) (flxrnd) (flxrnd))) ; randomise the vertex position
     (if (zero? n)
         0
         (mashup (- n 1)))) ; loops till n is 0

 (define shape (build-sphere 10 10))
 (grab shape)
 (mashup (pdata-size)) ; randomise verts on currently grabbed primitive
 (ungrab)

(recalc-normals smoothornot-number)

Returns void

For polygon primitives only. Looks at the vertex positions and calculates the lighting normals for you automatically. Call with "1" for smooth normals, "0" for faceted normals.

Example

 (define shape (build-sphere 10 10)) ; build a sphere (which is smooth by default)
 (grab shape)
 (recalc-normals 0) ; make the sphere faceted
 (ungrab)