irteusでPQPを使うためのファイルは CPQP.C, euspqp.c, pqp.l からなる. 2つの幾何モデルが衝突してしるか否かを判定するためには,
(defun pqp-collision-check (model1 model2
&optional (flag PQP_FIRST_CONTACT) &key (fat 0) (fat2 nil))
(let ((m1 (get model1 :pqpmodel)) (m2 (get model2 :pqpmodel))
(r1 (send model1 :worldrot)) (t1 (send model1 :worldpos))
(r2 (send model2 :worldrot)) (t2 (send model2 :worldpos)))
(if (null fat2) (setq fat2 fat))
(if (null m1) (setq m1 (send model1 :make-pqpmodel :fat fat)))
(if (null m2) (setq m2 (send model2 :make-pqpmodel :fat fat2)))
(pqpcollide r1 t1 m1 r2 t2 m2 flag)))
を呼び出せば良い.
r1,r1,r2,t1はそれぞれの物体の並進ベクトル,回転行列となり,
(get model1 :pqpmodel)でPQPの幾何モデルへのポインタを参照する.
このポインタは:make-pqpmodelメソッドの中で以下のよう計算される.
(defmethod cascaded-coords
(:make-pqpmodel
(&key (fat 0))
(let ((m (pqpmakemodel))
vs v1 v2 v3 (id 0))
(setf (get self :pqpmodel) m)
(pqpbeginmodel m)
(dolist (f (send self :faces))
(dolist (poly (face-to-triangle-aux f))
(setq vs (send poly :vertices)
v1 (send self :inverse-transform-vector (first vs))
v2 (send self :inverse-transform-vector (second vs))
v3 (send self :inverse-transform-vector (third vs)))
(when (not (= fat 0))
(setq v1 (v+ v1 (scale fat (normalize-vector v1)))
v2 (v+ v2 (scale fat (normalize-vector v2)))
v3 (v+ v3 (scale fat (normalize-vector v3)))))
(pqpaddtri m v1 v2 v3 id)
(incf id)))
(pqpendmodel m)
m)))
ここでは,まず(pqpmakemodel)が呼び出されている.
pqpmakemodelの中では,euqpqp.cで定義されている,
pointer PQPMAKEMODEL(register context *ctx, int n, register pointer *argv)
{
int addr = PQP_MakeModel();
return makeint(addr);
}
が呼び出されており,これは,CPQP.Cの
PQP\_Model *PQP_MakeModel()
{
return new PQP_Model();
}
が呼ばれている.PQP_Model()はPQP.hで定義されているものであり,
この様にしてeuslisp内の関数が実際のPQPライブラリの関数に渡されてい
る以降,(pqpbeginmodel m)でPQPの幾何モデルのインスタンスを作成し,
(pqpaddtri m v1 v2 v3 id)として面情報を登録している.