Initial checkin of Pika from heckimp
This commit is contained in:
22
plug-ins/map-object/CHANGES
Normal file
22
plug-ins/map-object/CHANGES
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
Changes (post 0.3.1):
|
||||
=====================
|
||||
|
||||
-> 0.3.1 Merged MapPlane and MapSphere. Added support for non-interactive
|
||||
execution (for script-fu).
|
||||
-> 0.3.2 Fixed a bug in the bilinear interpolation function. Added "tile" option.
|
||||
Added some icons to the material page to illustrate the effects of the
|
||||
parameters. I'm not sure they help much.
|
||||
-> 0.4.0 Some source/algorithm cleanups, fixed gtk+ object refcounting bugs. Some
|
||||
changes to compile with gtk+ 0.99.4.
|
||||
-> 1.0.0 First non-beta release. Replaced GckNotebook with GtkNotebook, fixed a few
|
||||
annoying bugs. Better support for partial transparency (only filtered
|
||||
transparency now, perhaps additive later). Compiles without warnings with
|
||||
-Wall and -ansi.
|
||||
-> 1.1.0 Added box object and changed PDB interface accordingly; this will unfortunately
|
||||
break old scripts. The transparency code should be a little saner now.
|
||||
-> 1.2.0 Added cylinder object. Fixed a few things, thanks to Yosh <yosh@gimp.org> and
|
||||
Pedro <pkaempf@master.echo.ch> for pointing them out to me.
|
||||
|
||||
|
||||
|
61
plug-ins/map-object/README
Normal file
61
plug-ins/map-object/README
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
MapObject 1.2.0 -- image filter plug-in for PIKA
|
||||
===========================================================
|
||||
|
||||
Copyright (C) 1996-98 Tom Bech
|
||||
Copyright (C) 1996-98 Federico Mena Quintero
|
||||
|
||||
Released 16th of July, 1998
|
||||
|
||||
You can reach the author(s) via E-mail:
|
||||
tomb@gimp.org (Tom) or quartic@gimp.org (Federico).
|
||||
|
||||
PIKA was developed by Peter Mattis and Spencer Kimball.
|
||||
You can contact them at pika@xcf.berkeley.edu.
|
||||
|
||||
There's more PIKA stuff on our home pages:
|
||||
http://www.ii.uib.no/~tomb/pika.html (Tom's page)
|
||||
http://www.nuclecu.unam.mx/~federico/pika/index.html (Quartic's page)
|
||||
|
||||
Legal stuff
|
||||
===========
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
In other words, you can't sue us for whatever happens while using this ;)
|
||||
|
||||
Compiling
|
||||
=========
|
||||
|
||||
To compile you'll need PIKA 1.0 and GTK+ 1.0.4 or later.
|
||||
You'll also need GCK 1.00 (http://www.ii.uib.no/~tomb/gck.html)
|
||||
|
||||
1) Edit the Makefile to reflect your system setup.
|
||||
|
||||
2) Type "make" and then "make install"
|
||||
|
||||
You should now be ready to run. "make install" puts the executable "MapObject"
|
||||
in the standard plug-in directory.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
Ahem.. right.. ;) ..I'll get around to it eventually.
|
||||
|
||||
Please send me a mail if you find any bugs.
|
||||
|
||||
Have fun,
|
||||
|
||||
Tom
|
||||
|
18
plug-ins/map-object/TODO
Normal file
18
plug-ins/map-object/TODO
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
The MapObject plug-in "todo"-list:
|
||||
=================================
|
||||
|
||||
* Interactive positioning of directional light
|
||||
* Rotation by mouse (doesn't work correctly yet and is disabled).
|
||||
* Faster mapping code
|
||||
* Multiple light-sources
|
||||
* More objects?
|
||||
* Presets (including save/load)
|
||||
* Gray-scale/channels support
|
||||
* Documentation
|
||||
* Autoconf/automake stuff?
|
||||
|
||||
If there's anything you would like to add, feel free
|
||||
to send me any suggestions for new stuff or improvements.
|
||||
|
||||
Tom
|
515
plug-ins/map-object/arcball.c
Normal file
515
plug-ins/map-object/arcball.c
Normal file
@ -0,0 +1,515 @@
|
||||
/************************************/
|
||||
/* ArcBall.c (c) Ken Shoemake, 1993 */
|
||||
/* Modified by Tom Bech, 1996 */
|
||||
/************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libpika/pika.h>
|
||||
|
||||
#include "arcball.h"
|
||||
|
||||
/* Global variables */
|
||||
/* ================ */
|
||||
|
||||
Quat qOne = { 0, 0, 0, 1 };
|
||||
|
||||
static HVect center;
|
||||
static double radius;
|
||||
static Quat qNow, qDown, qDrag;
|
||||
static HVect vNow, vDown, vFrom, vTo, vrFrom, vrTo;
|
||||
static HMatrix mNow, mDown;
|
||||
static unsigned int showResult, dragging;
|
||||
static ConstraintSet sets[NSets];
|
||||
static int setSizes[NSets];
|
||||
static AxisSet axisSet;
|
||||
static int axisIndex;
|
||||
|
||||
static HMatrix mId =
|
||||
{
|
||||
{ 1, 0, 0, 0 },
|
||||
{ 0, 1, 0, 0 },
|
||||
{ 0, 0, 1, 0 },
|
||||
{ 0, 0, 0, 1 }
|
||||
};
|
||||
|
||||
static double otherAxis[][4] =
|
||||
{
|
||||
{-0.48, 0.80, 0.36, 1}
|
||||
};
|
||||
|
||||
/* Internal methods */
|
||||
/* ================ */
|
||||
|
||||
static void Qt_ToMatrix(Quat q,HMatrix out);
|
||||
static Quat Qt_Conj(Quat q);
|
||||
static Quat Qt_Mul(Quat qL, Quat qR);
|
||||
static Quat Qt_FromBallPoints(HVect from, HVect to);
|
||||
static void Qt_ToBallPoints(Quat q, HVect *arcFrom, HVect *arcTo);
|
||||
|
||||
static HVect V3_(double x, double y, double z);
|
||||
static double V3_Norm(HVect v);
|
||||
static HVect V3_Unit(HVect v);
|
||||
static HVect V3_Scale(HVect v, double s);
|
||||
static HVect V3_Negate(HVect v);
|
||||
/*
|
||||
static HVect V3_Add(HVect v1, HVect v2);
|
||||
*/
|
||||
static HVect V3_Sub(HVect v1, HVect v2);
|
||||
static double V3_Dot(HVect v1, HVect v2);
|
||||
/*
|
||||
static HVect V3_Cross(HVect v1, HVect v2);
|
||||
static HVect V3_Bisect(HVect v0, HVect v1);
|
||||
*/
|
||||
|
||||
static HVect MouseOnSphere(HVect mouse, HVect ballCenter, double ballRadius);
|
||||
static HVect ConstrainToAxis(HVect loose, HVect axis);
|
||||
static int NearestConstraintAxis(HVect loose, HVect *axes, int nAxes);
|
||||
|
||||
/* Establish reasonable initial values for controller. */
|
||||
/* =================================================== */
|
||||
|
||||
void
|
||||
ArcBall_Init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
center = qOne;
|
||||
radius = 1.0;
|
||||
vDown = vNow = qOne;
|
||||
qDown = qNow = qOne;
|
||||
for (i=15; i>=0; i--)
|
||||
((double *)mNow)[i] = ((double *)mDown)[i] = ((double *)mId)[i];
|
||||
|
||||
showResult = dragging = FALSE;
|
||||
axisSet = NoAxes;
|
||||
sets[CameraAxes] = mId[X];
|
||||
setSizes[CameraAxes] = 3;
|
||||
sets[BodyAxes] = mDown[X];
|
||||
setSizes[BodyAxes] = 3;
|
||||
sets[OtherAxes] = otherAxis[X];
|
||||
setSizes[OtherAxes] = 1;
|
||||
}
|
||||
|
||||
/* Set the center and size of the controller. */
|
||||
/* ========================================== */
|
||||
|
||||
void
|
||||
ArcBall_Place (HVect Center,
|
||||
double Radius)
|
||||
{
|
||||
center = Center;
|
||||
radius = Radius;
|
||||
}
|
||||
|
||||
/* Incorporate new mouse position. */
|
||||
/* =============================== */
|
||||
|
||||
void
|
||||
ArcBall_Mouse (HVect v_Now)
|
||||
{
|
||||
vNow = v_Now;
|
||||
}
|
||||
|
||||
/* Choose a constraint set, or none. */
|
||||
/* ================================= */
|
||||
|
||||
void
|
||||
ArcBall_UseSet (AxisSet axis_Set)
|
||||
{
|
||||
if (!dragging) axisSet = axis_Set;
|
||||
}
|
||||
|
||||
/* Using vDown, vNow, dragging, and axisSet, compute rotation etc. */
|
||||
/* =============================================================== */
|
||||
|
||||
void
|
||||
ArcBall_Update (void)
|
||||
{
|
||||
int setSize = setSizes[axisSet];
|
||||
HVect *set = (HVect *)(sets[axisSet]);
|
||||
|
||||
vFrom = MouseOnSphere(vDown, center, radius);
|
||||
vTo = MouseOnSphere(vNow, center, radius);
|
||||
if (dragging)
|
||||
{
|
||||
if (axisSet!=NoAxes)
|
||||
{
|
||||
vFrom = ConstrainToAxis(vFrom, set[axisIndex]);
|
||||
vTo = ConstrainToAxis(vTo, set[axisIndex]);
|
||||
}
|
||||
qDrag = Qt_FromBallPoints(vFrom, vTo);
|
||||
qNow = Qt_Mul(qDrag, qDown);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axisSet!=NoAxes) axisIndex = NearestConstraintAxis(vTo, set, setSize);
|
||||
}
|
||||
Qt_ToBallPoints(qDown, &vrFrom, &vrTo);
|
||||
Qt_ToMatrix(Qt_Conj(qNow), mNow); /* Gives transpose for GL. */
|
||||
}
|
||||
|
||||
/* Return rotation matrix defined by controller use. */
|
||||
/* ================================================= */
|
||||
|
||||
void
|
||||
ArcBall_Value (HMatrix m_Now)
|
||||
{
|
||||
ArcBall_CopyMat (mNow, m_Now);
|
||||
}
|
||||
|
||||
/* Extract rotation angles from matrix */
|
||||
/* =================================== */
|
||||
|
||||
void
|
||||
ArcBall_Values (double *alpha,
|
||||
double *beta,
|
||||
double *gamma)
|
||||
{
|
||||
if ((*beta=asin(-mNow[0][2]))!=0.0)
|
||||
{
|
||||
*gamma=atan2(mNow[1][2],mNow[2][2]);
|
||||
*alpha=atan2(mNow[0][1],mNow[0][0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
*gamma=atan2(mNow[1][0],mNow[1][1]);
|
||||
*alpha=0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin drag sequence. */
|
||||
/* ==================== */
|
||||
|
||||
void
|
||||
ArcBall_BeginDrag (void)
|
||||
{
|
||||
dragging = TRUE;
|
||||
vDown = vNow;
|
||||
}
|
||||
|
||||
/* Stop drag sequence. */
|
||||
/* =================== */
|
||||
|
||||
void
|
||||
ArcBall_EndDrag (void)
|
||||
{
|
||||
dragging = FALSE;
|
||||
qDown = qNow;
|
||||
|
||||
ArcBall_CopyMat (mNow, mDown);
|
||||
}
|
||||
|
||||
/*===================*/
|
||||
/***** BallAux.c *****/
|
||||
/*===================*/
|
||||
|
||||
/* Return quaternion product qL * qR. Note: order is important! */
|
||||
/* To combine rotations, use the product Mul(qSecond, qFirst), */
|
||||
/* which gives the effect of rotating by qFirst then qSecond. */
|
||||
/* ============================================================= */
|
||||
|
||||
static Quat
|
||||
Qt_Mul (Quat qL,
|
||||
Quat qR)
|
||||
{
|
||||
Quat qq;
|
||||
qq.w = qL.w*qR.w - qL.x*qR.x - qL.y*qR.y - qL.z*qR.z;
|
||||
qq.x = qL.w*qR.x + qL.x*qR.w + qL.y*qR.z - qL.z*qR.y;
|
||||
qq.y = qL.w*qR.y + qL.y*qR.w + qL.z*qR.x - qL.x*qR.z;
|
||||
qq.z = qL.w*qR.z + qL.z*qR.w + qL.x*qR.y - qL.y*qR.x;
|
||||
return (qq);
|
||||
}
|
||||
|
||||
/* Construct rotation matrix from (possibly non-unit) quaternion. */
|
||||
/* Assumes matrix is used to multiply column vector on the left: */
|
||||
/* vnew = mat vold. Works correctly for right-handed coordinate */
|
||||
/* system and right-handed rotations. */
|
||||
/* ============================================================== */
|
||||
|
||||
static void
|
||||
Qt_ToMatrix (Quat q,
|
||||
HMatrix out)
|
||||
{
|
||||
double Nq = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w;
|
||||
double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
|
||||
double xs = q.x*s, ys = q.y*s, zs = q.z*s;
|
||||
double wx = q.w*xs, wy = q.w*ys, wz = q.w*zs;
|
||||
double xx = q.x*xs, xy = q.x*ys, xz = q.x*zs;
|
||||
double yy = q.y*ys, yz = q.y*zs, zz = q.z*zs;
|
||||
out[X][X] = 1.0 - (yy + zz); out[Y][X] = xy + wz; out[Z][X] = xz - wy;
|
||||
out[X][Y] = xy - wz; out[Y][Y] = 1.0 - (xx + zz); out[Z][Y] = yz + wx;
|
||||
out[X][Z] = xz + wy; out[Y][Z] = yz - wx; out[Z][Z] = 1.0 - (xx + yy);
|
||||
out[X][W] = out[Y][W] = out[Z][W] = out[W][X] = out[W][Y] = out[W][Z] = 0.0;
|
||||
out[W][W] = 1.0;
|
||||
}
|
||||
|
||||
/* Return conjugate of quaternion. */
|
||||
/* =============================== */
|
||||
|
||||
static Quat
|
||||
Qt_Conj (Quat q)
|
||||
{
|
||||
Quat qq;
|
||||
qq.x = -q.x; qq.y = -q.y; qq.z = -q.z; qq.w = q.w;
|
||||
return (qq);
|
||||
}
|
||||
|
||||
/* Return vector formed from components */
|
||||
/* ==================================== */
|
||||
|
||||
static HVect
|
||||
V3_ (double x,
|
||||
double y,
|
||||
double z)
|
||||
{
|
||||
HVect v;
|
||||
v.x = x; v.y = y; v.z = z; v.w = 0;
|
||||
return (v);
|
||||
}
|
||||
|
||||
/* Return norm of v, defined as sum of squares of components */
|
||||
/* ========================================================= */
|
||||
|
||||
static double
|
||||
V3_Norm (HVect v)
|
||||
{
|
||||
return ( v.x*v.x + v.y*v.y + v.z*v.z );
|
||||
}
|
||||
|
||||
/* Return unit magnitude vector in direction of v */
|
||||
/* ============================================== */
|
||||
|
||||
static HVect
|
||||
V3_Unit (HVect v)
|
||||
{
|
||||
static HVect u = {0, 0, 0, 0};
|
||||
double vlen = sqrt(V3_Norm(v));
|
||||
|
||||
if (vlen != 0.0)
|
||||
{
|
||||
u.x = v.x/vlen;
|
||||
u.y = v.y/vlen;
|
||||
u.z = v.z/vlen;
|
||||
}
|
||||
return (u);
|
||||
}
|
||||
|
||||
/* Return version of v scaled by s */
|
||||
/* =============================== */
|
||||
|
||||
static HVect
|
||||
V3_Scale (HVect v,
|
||||
double s)
|
||||
{
|
||||
HVect u;
|
||||
u.x = s*v.x; u.y = s*v.y; u.z = s*v.z; u.w = v.w;
|
||||
return (u);
|
||||
}
|
||||
|
||||
/* Return negative of v */
|
||||
/* ==================== */
|
||||
|
||||
static HVect
|
||||
V3_Negate (HVect v)
|
||||
{
|
||||
static HVect u = {0, 0, 0, 0};
|
||||
u.x = -v.x; u.y = -v.y; u.z = -v.z;
|
||||
return (u);
|
||||
}
|
||||
|
||||
/* Return sum of v1 and v2 */
|
||||
/* ======================= */
|
||||
/*
|
||||
static HVect
|
||||
V3_Add (HVect v1,
|
||||
HVect v2)
|
||||
{
|
||||
static HVect v = {0, 0, 0, 0};
|
||||
v.x = v1.x+v2.x; v.y = v1.y+v2.y; v.z = v1.z+v2.z;
|
||||
return (v);
|
||||
}
|
||||
*/
|
||||
/* Return difference of v1 minus v2 */
|
||||
/* ================================ */
|
||||
|
||||
static HVect
|
||||
V3_Sub (HVect v1,
|
||||
HVect v2)
|
||||
{
|
||||
static HVect v = {0, 0, 0, 0};
|
||||
v.x = v1.x-v2.x; v.y = v1.y-v2.y; v.z = v1.z-v2.z;
|
||||
return (v);
|
||||
}
|
||||
|
||||
/* Halve arc between unit vectors v0 and v1. */
|
||||
/* ========================================= */
|
||||
/*
|
||||
static HVect
|
||||
V3_Bisect (HVect v0,
|
||||
HVect v1)
|
||||
{
|
||||
HVect v = {0, 0, 0, 0};
|
||||
double Nv;
|
||||
|
||||
v = V3_Add(v0, v1);
|
||||
Nv = V3_Norm(v);
|
||||
if (Nv < 1.0e-5) v = V3_(0, 0, 1);
|
||||
else v = V3_Scale(v, 1/sqrt(Nv));
|
||||
return (v);
|
||||
}
|
||||
*/
|
||||
|
||||
/* Return dot product of v1 and v2 */
|
||||
/* =============================== */
|
||||
|
||||
static double
|
||||
V3_Dot (HVect v1,
|
||||
HVect v2)
|
||||
{
|
||||
return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
|
||||
}
|
||||
|
||||
|
||||
/* Return cross product, v1 x v2 */
|
||||
/* ============================= */
|
||||
/*
|
||||
static HVect
|
||||
V3_Cross (HVect v1,
|
||||
HVect v2)
|
||||
{
|
||||
static HVect v = {0, 0, 0, 0};
|
||||
v.x = v1.y*v2.z-v1.z*v2.y;
|
||||
v.y = v1.z*v2.x-v1.x*v2.z;
|
||||
v.z = v1.x*v2.y-v1.y*v2.x;
|
||||
return (v);
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
ArcBall_CopyMat (HMatrix inm,
|
||||
HMatrix outm)
|
||||
{
|
||||
int x=0,y=0;
|
||||
|
||||
for (x=0;x<4;x++)
|
||||
{
|
||||
for (y=0;y<4;y++)
|
||||
{
|
||||
outm[y][x]=inm[y][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*=====================================================*/
|
||||
/**** BallMath.c - Essential routines for ArcBall. ****/
|
||||
/*=====================================================*/
|
||||
|
||||
/* Convert window coordinates to sphere coordinates. */
|
||||
/* ================================================= */
|
||||
|
||||
static HVect
|
||||
MouseOnSphere (HVect mouse,
|
||||
HVect ballCenter,
|
||||
double ballRadius)
|
||||
{
|
||||
HVect ballMouse;
|
||||
register double mag;
|
||||
|
||||
ballMouse.x = (mouse.x - ballCenter.x) / ballRadius;
|
||||
ballMouse.y = (mouse.y - ballCenter.y) / ballRadius;
|
||||
mag = ballMouse.x*ballMouse.x + ballMouse.y*ballMouse.y;
|
||||
if (mag > 1.0)
|
||||
{
|
||||
register double scale = 1.0/sqrt(mag);
|
||||
ballMouse.x *= scale; ballMouse.y *= scale;
|
||||
ballMouse.z = 0.0;
|
||||
}
|
||||
else ballMouse.z = sqrt(1 - mag);
|
||||
ballMouse.w = 0.0;
|
||||
return (ballMouse);
|
||||
}
|
||||
|
||||
/* Construct a unit quaternion from two points on unit sphere */
|
||||
/* ========================================================== */
|
||||
|
||||
static Quat
|
||||
Qt_FromBallPoints (HVect from,
|
||||
HVect to)
|
||||
{
|
||||
Quat qu;
|
||||
qu.x = from.y*to.z - from.z*to.y;
|
||||
qu.y = from.z*to.x - from.x*to.z;
|
||||
qu.z = from.x*to.y - from.y*to.x;
|
||||
qu.w = from.x*to.x + from.y*to.y + from.z*to.z;
|
||||
return (qu);
|
||||
}
|
||||
|
||||
/* Convert a unit quaternion to two points on unit sphere */
|
||||
/* ====================================================== */
|
||||
|
||||
static void
|
||||
Qt_ToBallPoints (Quat q,
|
||||
HVect *arcFrom,
|
||||
HVect *arcTo)
|
||||
{
|
||||
double s;
|
||||
|
||||
s = sqrt(q.x*q.x + q.y*q.y);
|
||||
if (s == 0.0) *arcFrom = V3_(0.0, 1.0, 0.0);
|
||||
else *arcFrom = V3_(-q.y/s, q.x/s, 0.0);
|
||||
arcTo->x = q.w*arcFrom->x - q.z*arcFrom->y;
|
||||
arcTo->y = q.w*arcFrom->y + q.z*arcFrom->x;
|
||||
arcTo->z = q.x*arcFrom->y - q.y*arcFrom->x;
|
||||
if (q.w < 0.0) *arcFrom = V3_(-arcFrom->x, -arcFrom->y, 0.0);
|
||||
}
|
||||
|
||||
/* Force sphere point to be perpendicular to axis. */
|
||||
/* =============================================== */
|
||||
|
||||
static HVect
|
||||
ConstrainToAxis (HVect loose,
|
||||
HVect axis)
|
||||
{
|
||||
HVect onPlane;
|
||||
register double norm;
|
||||
|
||||
onPlane = V3_Sub(loose, V3_Scale(axis, V3_Dot(axis, loose)));
|
||||
norm = V3_Norm(onPlane);
|
||||
if (norm > 0.0)
|
||||
{
|
||||
if (onPlane.z < 0.0) onPlane = V3_Negate(onPlane);
|
||||
return ( V3_Scale(onPlane, 1/sqrt(norm)) );
|
||||
}
|
||||
/* else drop through */
|
||||
/* ================= */
|
||||
|
||||
if (axis.z == 1) onPlane = V3_(1.0, 0.0, 0.0);
|
||||
else onPlane = V3_Unit(V3_(-axis.y, axis.x, 0.0));
|
||||
return (onPlane);
|
||||
}
|
||||
|
||||
/* Find the index of nearest arc of axis set. */
|
||||
/* ========================================== */
|
||||
|
||||
static int
|
||||
NearestConstraintAxis (HVect loose,
|
||||
HVect *axes,
|
||||
int nAxes)
|
||||
{
|
||||
HVect onPlane;
|
||||
register double max, dot;
|
||||
register int i, nearest;
|
||||
max = -1; nearest = 0;
|
||||
|
||||
for (i=0; i<nAxes; i++)
|
||||
{
|
||||
onPlane = ConstrainToAxis(loose, axes[i]);
|
||||
dot = V3_Dot(onPlane, loose);
|
||||
if (dot>max)
|
||||
{
|
||||
max = dot; nearest = i;
|
||||
}
|
||||
}
|
||||
return (nearest);
|
||||
}
|
50
plug-ins/map-object/arcball.h
Normal file
50
plug-ins/map-object/arcball.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef __ARCBALL_H__
|
||||
#define __ARCBALL_H__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x, y, z, w;
|
||||
} Quat;
|
||||
|
||||
enum QuatPart
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
W,
|
||||
QuatLen
|
||||
};
|
||||
|
||||
typedef Quat HVect;
|
||||
|
||||
typedef double HMatrix[QuatLen][QuatLen];
|
||||
|
||||
typedef enum AxisSet
|
||||
{
|
||||
NoAxes,
|
||||
CameraAxes,
|
||||
BodyAxes,
|
||||
OtherAxes,
|
||||
NSets
|
||||
} AxisSet;
|
||||
|
||||
typedef double *ConstraintSet;
|
||||
|
||||
extern Quat qOne;
|
||||
|
||||
void ArcBall_Init (void);
|
||||
void ArcBall_Place (HVect Center,
|
||||
double Radius);
|
||||
void ArcBall_UseSet (AxisSet axis_Set);
|
||||
void ArcBall_Update (void);
|
||||
void ArcBall_Value (HMatrix m_Now);
|
||||
void ArcBall_Values (double *alpha,
|
||||
double *beta,
|
||||
double *gamma);
|
||||
void ArcBall_BeginDrag (void);
|
||||
void ArcBall_EndDrag (void);
|
||||
void ArcBall_Mouse (HVect v_Now);
|
||||
void ArcBall_CopyMat (HMatrix inm,
|
||||
HMatrix outm);
|
||||
|
||||
#endif /* __ARCBALL_H__ */
|
328
plug-ins/map-object/map-object-apply.c
Normal file
328
plug-ins/map-object/map-object-apply.c
Normal file
@ -0,0 +1,328 @@
|
||||
/******************************************************/
|
||||
/* Apply mapping and shading on the whole input image */
|
||||
/******************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libpika/pika.h>
|
||||
#include <libpika/pikaui.h>
|
||||
|
||||
#include "map-object-main.h"
|
||||
#include "map-object-image.h"
|
||||
#include "map-object-shade.h"
|
||||
#include "map-object-apply.h"
|
||||
|
||||
#include "libpika/stdplugins-intl.h"
|
||||
|
||||
|
||||
/*************/
|
||||
/* Main loop */
|
||||
/*************/
|
||||
|
||||
gdouble imat[4][4];
|
||||
gfloat rotmat[16];
|
||||
static gfloat a[16], b[16];
|
||||
|
||||
void
|
||||
init_compute (void)
|
||||
{
|
||||
gint i;
|
||||
|
||||
switch (mapvals.maptype)
|
||||
{
|
||||
case MAP_SPHERE:
|
||||
|
||||
/* Rotate the equator/northpole axis */
|
||||
/* ================================= */
|
||||
|
||||
pika_vector3_set (&mapvals.firstaxis, 0.0, 0.0, -1.0);
|
||||
pika_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
||||
|
||||
pika_vector3_rotate (&mapvals.firstaxis,
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
pika_vector3_rotate (&mapvals.secondaxis,
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
|
||||
/* Compute the 2D bounding box of the sphere spanned by the axis */
|
||||
/* ============================================================= */
|
||||
|
||||
compute_bounding_box ();
|
||||
|
||||
get_ray_color = get_ray_color_sphere;
|
||||
|
||||
break;
|
||||
|
||||
case MAP_PLANE:
|
||||
|
||||
/* Rotate the plane axis */
|
||||
/* ===================== */
|
||||
|
||||
pika_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0);
|
||||
pika_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
||||
pika_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0);
|
||||
|
||||
pika_vector3_rotate (&mapvals.firstaxis,
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
pika_vector3_rotate (&mapvals.secondaxis,
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
|
||||
mapvals.normal = pika_vector3_cross_product (&mapvals.firstaxis,
|
||||
&mapvals.secondaxis);
|
||||
|
||||
if (mapvals.normal.z < 0.0)
|
||||
pika_vector3_mul (&mapvals.normal, -1.0);
|
||||
|
||||
/* Initialize intersection matrix */
|
||||
/* ============================== */
|
||||
|
||||
imat[0][1] = -mapvals.firstaxis.x;
|
||||
imat[1][1] = -mapvals.firstaxis.y;
|
||||
imat[2][1] = -mapvals.firstaxis.z;
|
||||
|
||||
imat[0][2] = -mapvals.secondaxis.x;
|
||||
imat[1][2] = -mapvals.secondaxis.y;
|
||||
imat[2][2] = -mapvals.secondaxis.z;
|
||||
|
||||
imat[0][3] = mapvals.position.x - mapvals.viewpoint.x;
|
||||
imat[1][3] = mapvals.position.y - mapvals.viewpoint.y;
|
||||
imat[2][3] = mapvals.position.z - mapvals.viewpoint.z;
|
||||
|
||||
get_ray_color = get_ray_color_plane;
|
||||
|
||||
break;
|
||||
|
||||
case MAP_BOX:
|
||||
get_ray_color = get_ray_color_box;
|
||||
|
||||
pika_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0);
|
||||
pika_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
||||
pika_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0);
|
||||
|
||||
ident_mat (rotmat);
|
||||
|
||||
rotatemat (mapvals.alpha, &mapvals.firstaxis, a);
|
||||
|
||||
matmul (a, rotmat, b);
|
||||
|
||||
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
||||
|
||||
rotatemat (mapvals.beta, &mapvals.secondaxis, a);
|
||||
matmul (a, rotmat, b);
|
||||
|
||||
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
||||
|
||||
rotatemat (mapvals.gamma, &mapvals.normal, a);
|
||||
matmul (a, rotmat, b);
|
||||
|
||||
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
||||
|
||||
/* Set up pixel regions for the box face images */
|
||||
/* ============================================ */
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
box_drawables[i] = pika_drawable_get_by_id (mapvals.boxmap_id[i]);
|
||||
|
||||
box_buffers[i] = pika_drawable_get_buffer (box_drawables[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MAP_CYLINDER:
|
||||
get_ray_color = get_ray_color_cylinder;
|
||||
|
||||
pika_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0);
|
||||
pika_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
||||
pika_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0);
|
||||
|
||||
ident_mat (rotmat);
|
||||
|
||||
rotatemat (mapvals.alpha, &mapvals.firstaxis, a);
|
||||
|
||||
matmul (a, rotmat, b);
|
||||
|
||||
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
||||
|
||||
rotatemat (mapvals.beta, &mapvals.secondaxis, a);
|
||||
matmul (a, rotmat, b);
|
||||
|
||||
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
||||
|
||||
rotatemat (mapvals.gamma, &mapvals.normal, a);
|
||||
matmul (a, rotmat, b);
|
||||
|
||||
memcpy (rotmat, b, sizeof (gfloat) * 16);
|
||||
|
||||
/* Set up pixel regions for the cylinder cap images */
|
||||
/* ================================================ */
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
cylinder_drawables[i] = pika_drawable_get_by_id (mapvals.cylindermap_id[i]);;
|
||||
|
||||
cylinder_buffers[i] = pika_drawable_get_buffer (cylinder_drawables[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
max_depth = (gint) mapvals.maxdepth;
|
||||
}
|
||||
|
||||
static void
|
||||
render (gdouble x,
|
||||
gdouble y,
|
||||
PikaRGB *col,
|
||||
gpointer data)
|
||||
{
|
||||
PikaVector3 pos;
|
||||
|
||||
pos.x = x / (gdouble) width;
|
||||
pos.y = y / (gdouble) height;
|
||||
pos.z = 0.0;
|
||||
|
||||
*col = get_ray_color (&pos);
|
||||
}
|
||||
|
||||
static void
|
||||
show_progress (gint min,
|
||||
gint max,
|
||||
gint curr,
|
||||
gpointer data)
|
||||
{
|
||||
pika_progress_update ((gdouble) curr / (gdouble) max);
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* Performs map-to-sphere on the whole input image */
|
||||
/* and updates or creates a new PIKA image. */
|
||||
/**************************************************/
|
||||
|
||||
void
|
||||
compute_image (void)
|
||||
{
|
||||
gint xcount, ycount;
|
||||
PikaRGB color;
|
||||
glong progress_counter = 0;
|
||||
PikaVector3 p;
|
||||
PikaImage *new_image = NULL;
|
||||
PikaLayer *new_layer = NULL;
|
||||
gboolean insert_layer = FALSE;
|
||||
|
||||
init_compute ();
|
||||
|
||||
if (mapvals.create_new_image)
|
||||
{
|
||||
new_image = pika_image_new (width, height, PIKA_RGB);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_image = image;
|
||||
}
|
||||
|
||||
pika_image_undo_group_start (new_image);
|
||||
|
||||
if (mapvals.create_new_image ||
|
||||
mapvals.create_new_layer ||
|
||||
(mapvals.transparent_background &&
|
||||
! pika_drawable_has_alpha (output_drawable)))
|
||||
{
|
||||
gchar *layername[] = {_("Map to plane"),
|
||||
_("Map to sphere"),
|
||||
_("Map to box"),
|
||||
_("Map to cylinder"),
|
||||
_("Background")};
|
||||
|
||||
new_layer = pika_layer_new (new_image,
|
||||
layername[mapvals.create_new_image ? 4 :
|
||||
mapvals.maptype],
|
||||
width, height,
|
||||
mapvals.transparent_background ?
|
||||
PIKA_RGBA_IMAGE :
|
||||
PIKA_RGB_IMAGE,
|
||||
100.0,
|
||||
pika_image_get_default_new_layer_mode (new_image));
|
||||
|
||||
insert_layer = TRUE;
|
||||
output_drawable = PIKA_DRAWABLE (new_layer);
|
||||
}
|
||||
|
||||
dest_buffer = pika_drawable_get_shadow_buffer (output_drawable);
|
||||
|
||||
switch (mapvals.maptype)
|
||||
{
|
||||
case MAP_PLANE:
|
||||
pika_progress_init (_("Map to plane"));
|
||||
break;
|
||||
case MAP_SPHERE:
|
||||
pika_progress_init (_("Map to sphere"));
|
||||
break;
|
||||
case MAP_BOX:
|
||||
pika_progress_init (_("Map to box"));
|
||||
break;
|
||||
case MAP_CYLINDER:
|
||||
pika_progress_init (_("Map to cylinder"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (! mapvals.antialiasing)
|
||||
{
|
||||
for (ycount = 0; ycount < height; ycount++)
|
||||
{
|
||||
for (xcount = 0; xcount < width; xcount++)
|
||||
{
|
||||
p = int_to_pos (xcount, ycount);
|
||||
color = (* get_ray_color) (&p);
|
||||
poke (xcount, ycount, &color, NULL);
|
||||
|
||||
progress_counter++;
|
||||
}
|
||||
|
||||
pika_progress_update ((gdouble) progress_counter /
|
||||
(gdouble) maxcounter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pika_adaptive_supersample_area (0, 0,
|
||||
width - 1, height - 1,
|
||||
max_depth,
|
||||
mapvals.pixelthreshold,
|
||||
render,
|
||||
NULL,
|
||||
poke,
|
||||
NULL,
|
||||
show_progress,
|
||||
NULL);
|
||||
}
|
||||
|
||||
pika_progress_update (1.0);
|
||||
|
||||
g_object_unref (source_buffer);
|
||||
g_object_unref (dest_buffer);
|
||||
|
||||
if (insert_layer)
|
||||
pika_image_insert_layer (new_image, new_layer, NULL, 0);
|
||||
|
||||
pika_drawable_merge_shadow (output_drawable, TRUE);
|
||||
pika_drawable_update (output_drawable, 0, 0, width, height);
|
||||
|
||||
if (new_image != image)
|
||||
{
|
||||
pika_display_new (new_image);
|
||||
pika_displays_flush ();
|
||||
}
|
||||
|
||||
pika_image_undo_group_end (new_image);
|
||||
}
|
10
plug-ins/map-object/map-object-apply.h
Normal file
10
plug-ins/map-object/map-object-apply.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __MAPOBJECT_APPLY_H__
|
||||
#define __MAPOBJECT_APPLY_H__
|
||||
|
||||
extern gdouble imat[4][4];
|
||||
extern gfloat rotmat[16];
|
||||
|
||||
void init_compute (void);
|
||||
void compute_image (void);
|
||||
|
||||
#endif /* __MAPOBJECT_APPLY_H__ */
|
42
plug-ins/map-object/map-object-icons.c
Normal file
42
plug-ins/map-object/map-object-icons.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "map-object-icons.h"
|
||||
|
||||
#include "../lighting/images/lighting-icon-images.h"
|
||||
|
||||
|
||||
void
|
||||
mapobject_icons_init (void)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
GtkIconTheme *icon_theme;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
initialized = TRUE;
|
||||
|
||||
icon_theme = gtk_icon_theme_get_default ();
|
||||
|
||||
gtk_icon_theme_add_resource_path (icon_theme, "/technology.heckin/lighting/icons");
|
||||
}
|
37
plug-ins/map-object/map-object-icons.h
Normal file
37
plug-ins/map-object/map-object-icons.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __MAPOBJECT_ICONS_H__
|
||||
#define __MAPOBJECT_ICONS_H__
|
||||
|
||||
|
||||
#define MAPOBJECT_INTENSITY_AMBIENT_LOW "lighting-intensity-ambient-low"
|
||||
#define MAPOBJECT_INTENSITY_AMBIENT_HIGH "lighting-intensity-ambient-high"
|
||||
#define MAPOBJECT_INTENSITY_DIFFUSE_LOW "lighting-intensity-diffuse-low"
|
||||
#define MAPOBJECT_INTENSITY_DIFFUSE_HIGH "lighting-intensity-diffuse-high"
|
||||
#define MAPOBJECT_REFLECTIVITY_DIFFUSE_LOW "lighting-reflectivity-diffuse-low"
|
||||
#define MAPOBJECT_REFLECTIVITY_DIFFUSE_HIGH "lighting-reflectivity-diffuse-high"
|
||||
#define MAPOBJECT_REFLECTIVITY_SPECULAR_LOW "lighting-reflectivity-specular-low"
|
||||
#define MAPOBJECT_REFLECTIVITY_SPECULAR_HIGH "lighting-reflectivity-specular-high"
|
||||
#define MAPOBJECT_REFLECTIVITY_HIGHLIGHT_LOW "lighting-reflectivity-highlight-low"
|
||||
#define MAPOBJECT_REFLECTIVITY_HIGHLIGHT_HIGH "lighting-reflectivity-highlight-high"
|
||||
|
||||
|
||||
void mapobject_icons_init (void);
|
||||
|
||||
|
||||
#endif /* __MAPOBJECT_ICONS_H__ */
|
354
plug-ins/map-object/map-object-image.c
Normal file
354
plug-ins/map-object/map-object-image.c
Normal file
@ -0,0 +1,354 @@
|
||||
/*********************************************************/
|
||||
/* Image manipulation routines. Calls mapobject_shade.c */
|
||||
/* functions to compute the shading of the image at each */
|
||||
/* pixel. These routines are used by the functions in */
|
||||
/* mapobject_preview.c and mapobject_apply.c */
|
||||
/*********************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libpika/pika.h>
|
||||
#include <libpika/pikaui.h>
|
||||
|
||||
#include "map-object-main.h"
|
||||
#include "map-object-preview.h"
|
||||
#include "map-object-shade.h"
|
||||
#include "map-object-ui.h"
|
||||
#include "map-object-image.h"
|
||||
|
||||
|
||||
PikaImage *image;
|
||||
|
||||
PikaDrawable *input_drawable;
|
||||
PikaDrawable *output_drawable;
|
||||
GeglBuffer *source_buffer;
|
||||
GeglBuffer *dest_buffer;
|
||||
|
||||
PikaDrawable *box_drawables[6];
|
||||
GeglBuffer *box_buffers[6];
|
||||
|
||||
PikaDrawable *cylinder_drawables[2];
|
||||
GeglBuffer *cylinder_buffers[2];
|
||||
|
||||
guchar *preview_rgb_data = NULL;
|
||||
gint preview_rgb_stride;
|
||||
cairo_surface_t *preview_surface = NULL;
|
||||
|
||||
glong maxcounter, old_depth, max_depth;
|
||||
gint width, height;
|
||||
PikaRGB background;
|
||||
|
||||
gint border_x, border_y, border_w, border_h;
|
||||
|
||||
/******************/
|
||||
/* Implementation */
|
||||
/******************/
|
||||
|
||||
PikaRGB
|
||||
peek (gint x,
|
||||
gint y)
|
||||
{
|
||||
PikaRGB color;
|
||||
|
||||
gegl_buffer_sample (source_buffer, x, y, NULL,
|
||||
&color, babl_format ("R'G'B'A double"),
|
||||
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
|
||||
|
||||
if (! babl_format_has_alpha (gegl_buffer_get_format (source_buffer)))
|
||||
color.a = 1.0;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
static PikaRGB
|
||||
peek_box_image (gint image,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
PikaRGB color;
|
||||
|
||||
gegl_buffer_sample (box_buffers[image], x, y, NULL,
|
||||
&color, babl_format ("R'G'B'A double"),
|
||||
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
|
||||
|
||||
if (! babl_format_has_alpha (gegl_buffer_get_format (box_buffers[image])))
|
||||
color.a = 1.0;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
static PikaRGB
|
||||
peek_cylinder_image (gint image,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
PikaRGB color;
|
||||
|
||||
gegl_buffer_sample (cylinder_buffers[image], x, y, NULL,
|
||||
&color, babl_format ("R'G'B'A double"),
|
||||
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
|
||||
|
||||
if (! babl_format_has_alpha (gegl_buffer_get_format (cylinder_buffers[image])))
|
||||
color.a = 1.0;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void
|
||||
poke (gint x,
|
||||
gint y,
|
||||
PikaRGB *color,
|
||||
gpointer user_data)
|
||||
{
|
||||
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, 1, 1), 0,
|
||||
babl_format ("R'G'B'A double"), color,
|
||||
GEGL_AUTO_ROWSTRIDE);
|
||||
}
|
||||
|
||||
gint
|
||||
checkbounds (gint x,
|
||||
gint y)
|
||||
{
|
||||
if (x < border_x ||
|
||||
y < border_y ||
|
||||
x >= border_x + border_w ||
|
||||
y >= border_y + border_h)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
checkbounds_box_image (gint image,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gint w, h;
|
||||
|
||||
w = gegl_buffer_get_width (box_buffers[image]);
|
||||
h = gegl_buffer_get_height (box_buffers[image]);
|
||||
|
||||
if (x < 0 || y < 0 || x >= w || y >= h)
|
||||
return FALSE ;
|
||||
else
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
static gint
|
||||
checkbounds_cylinder_image (gint image,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gint w, h;
|
||||
|
||||
w = gegl_buffer_get_width (cylinder_buffers[image]);
|
||||
h = gegl_buffer_get_height (cylinder_buffers[image]);
|
||||
|
||||
if (x < 0 || y < 0 || x >= w || y >= h)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PikaVector3
|
||||
int_to_pos (gint x,
|
||||
gint y)
|
||||
{
|
||||
PikaVector3 pos;
|
||||
|
||||
pos.x = (gdouble) x / (gdouble) width;
|
||||
pos.y = (gdouble) y / (gdouble) height;
|
||||
pos.z = 0.0;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void
|
||||
pos_to_int (gdouble x,
|
||||
gdouble y,
|
||||
gint *scr_x,
|
||||
gint *scr_y)
|
||||
{
|
||||
*scr_x = (gint) ((x * (gdouble) width));
|
||||
*scr_y = (gint) ((y * (gdouble) height));
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
/* Compute the image color at pos (u,v) using */
|
||||
/* Quartics bilinear interpolation stuff. */
|
||||
/**********************************************/
|
||||
|
||||
PikaRGB
|
||||
get_image_color (gdouble u,
|
||||
gdouble v,
|
||||
gint *inside)
|
||||
{
|
||||
gint x1, y1, x2, y2;
|
||||
PikaRGB p[4];
|
||||
|
||||
pos_to_int (u, v, &x1, &y1);
|
||||
|
||||
if (mapvals.tiled == TRUE)
|
||||
{
|
||||
*inside = TRUE;
|
||||
|
||||
if (x1 < 0) x1 = (width-1) - (-x1 % width);
|
||||
else x1 = x1 % width;
|
||||
|
||||
if (y1 < 0) y1 = (height-1) - (-y1 % height);
|
||||
else y1 = y1 % height;
|
||||
|
||||
x2 = (x1 + 1) % width;
|
||||
y2 = (y1 + 1) % height;
|
||||
|
||||
p[0] = peek (x1, y1);
|
||||
p[1] = peek (x2, y1);
|
||||
p[2] = peek (x1, y2);
|
||||
p[3] = peek (x2, y2);
|
||||
|
||||
return pika_bilinear_rgba (u * width, v * height, p);
|
||||
}
|
||||
|
||||
if (checkbounds (x1, y1) == FALSE)
|
||||
{
|
||||
*inside =FALSE;
|
||||
|
||||
return background;
|
||||
}
|
||||
|
||||
x2 = (x1 + 1);
|
||||
y2 = (y1 + 1);
|
||||
|
||||
if (checkbounds (x2, y2) == FALSE)
|
||||
{
|
||||
*inside = TRUE;
|
||||
|
||||
return peek (x1, y1);
|
||||
}
|
||||
|
||||
*inside=TRUE;
|
||||
|
||||
p[0] = peek (x1, y1);
|
||||
p[1] = peek (x2, y1);
|
||||
p[2] = peek (x1, y2);
|
||||
p[3] = peek (x2, y2);
|
||||
|
||||
return pika_bilinear_rgba (u * width, v * height, p);
|
||||
}
|
||||
|
||||
PikaRGB
|
||||
get_box_image_color (gint image,
|
||||
gdouble u,
|
||||
gdouble v)
|
||||
{
|
||||
gint w, h;
|
||||
gint x1, y1, x2, y2;
|
||||
PikaRGB p[4];
|
||||
|
||||
w = gegl_buffer_get_width (box_buffers[image]);
|
||||
h = gegl_buffer_get_height (box_buffers[image]);
|
||||
|
||||
x1 = (gint) ((u * (gdouble) w));
|
||||
y1 = (gint) ((v * (gdouble) h));
|
||||
|
||||
if (checkbounds_box_image (image, x1, y1) == FALSE)
|
||||
return background;
|
||||
|
||||
x2 = (x1 + 1);
|
||||
y2 = (y1 + 1);
|
||||
|
||||
if (checkbounds_box_image (image, x2, y2) == FALSE)
|
||||
return peek_box_image (image, x1,y1);
|
||||
|
||||
p[0] = peek_box_image (image, x1, y1);
|
||||
p[1] = peek_box_image (image, x2, y1);
|
||||
p[2] = peek_box_image (image, x1, y2);
|
||||
p[3] = peek_box_image (image, x2, y2);
|
||||
|
||||
return pika_bilinear_rgba (u * w, v * h, p);
|
||||
}
|
||||
|
||||
PikaRGB
|
||||
get_cylinder_image_color (gint image,
|
||||
gdouble u,
|
||||
gdouble v)
|
||||
{
|
||||
gint w, h;
|
||||
gint x1, y1, x2, y2;
|
||||
PikaRGB p[4];
|
||||
|
||||
w = gegl_buffer_get_width (cylinder_buffers[image]);
|
||||
h = gegl_buffer_get_height (cylinder_buffers[image]);
|
||||
|
||||
x1 = (gint) ((u * (gdouble) w));
|
||||
y1 = (gint) ((v * (gdouble) h));
|
||||
|
||||
if (checkbounds_cylinder_image (image, x1, y1) == FALSE)
|
||||
return background;
|
||||
|
||||
x2 = (x1 + 1);
|
||||
y2 = (y1 + 1);
|
||||
|
||||
if (checkbounds_cylinder_image (image, x2, y2) == FALSE)
|
||||
return peek_cylinder_image (image, x1,y1);
|
||||
|
||||
p[0] = peek_cylinder_image (image, x1, y1);
|
||||
p[1] = peek_cylinder_image (image, x2, y1);
|
||||
p[2] = peek_cylinder_image (image, x1, y2);
|
||||
p[3] = peek_cylinder_image (image, x2, y2);
|
||||
|
||||
return pika_bilinear_rgba (u * w, v * h, p);
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Allocate memory for temporary images */
|
||||
/****************************************/
|
||||
|
||||
gint
|
||||
image_setup (PikaDrawable *drawable,
|
||||
gint interactive)
|
||||
{
|
||||
input_drawable = drawable;
|
||||
output_drawable = drawable;
|
||||
|
||||
if (! pika_drawable_mask_intersect (drawable, &border_x, &border_y,
|
||||
&border_w, &border_h))
|
||||
return FALSE;
|
||||
|
||||
width = pika_drawable_get_width (input_drawable);
|
||||
height = pika_drawable_get_height (input_drawable);
|
||||
|
||||
source_buffer = pika_drawable_get_buffer (input_drawable);
|
||||
|
||||
maxcounter = (glong) width * (glong) height;
|
||||
|
||||
if (mapvals.transparent_background == TRUE)
|
||||
{
|
||||
pika_rgba_set (&background, 0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pika_context_get_background (&background);
|
||||
pika_rgb_set_alpha (&background, 1.0);
|
||||
}
|
||||
|
||||
if (interactive == TRUE)
|
||||
{
|
||||
preview_rgb_stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24,
|
||||
PREVIEW_WIDTH);
|
||||
preview_rgb_data = g_new0 (guchar, preview_rgb_stride * PREVIEW_HEIGHT);
|
||||
preview_surface = cairo_image_surface_create_for_data (preview_rgb_data,
|
||||
CAIRO_FORMAT_RGB24,
|
||||
PREVIEW_WIDTH,
|
||||
PREVIEW_HEIGHT,
|
||||
preview_rgb_stride);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
64
plug-ins/map-object/map-object-image.h
Normal file
64
plug-ins/map-object/map-object-image.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef __MAPOBJECT_IMAGE_H__
|
||||
#define __MAPOBJECT_IMAGE_H__
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern PikaImage *image;
|
||||
|
||||
extern PikaDrawable *input_drawable;
|
||||
extern PikaDrawable *output_drawable;
|
||||
extern GeglBuffer *source_buffer;
|
||||
extern GeglBuffer *dest_buffer;
|
||||
|
||||
extern PikaDrawable *box_drawables[6];
|
||||
extern GeglBuffer *box_buffers[6];
|
||||
|
||||
extern PikaDrawable *cylinder_drawables[2];
|
||||
extern GeglBuffer *cylinder_buffers[2];
|
||||
|
||||
extern guchar *preview_rgb_data;
|
||||
extern gint preview_rgb_stride;
|
||||
extern cairo_surface_t *preview_surface;
|
||||
|
||||
extern glong maxcounter, old_depth, max_depth;
|
||||
extern gint width, height;
|
||||
extern PikaRGB background;
|
||||
|
||||
extern gint border_x1, border_y1, border_x2, border_y2;
|
||||
|
||||
/* Externally visible functions */
|
||||
/* ============================ */
|
||||
|
||||
extern gint image_setup (PikaDrawable *drawable,
|
||||
gint interactive);
|
||||
extern glong in_xy_to_index (gint x,
|
||||
gint y);
|
||||
extern glong out_xy_to_index (gint x,
|
||||
gint y);
|
||||
extern gint checkbounds (gint x,
|
||||
gint y);
|
||||
extern PikaRGB peek (gint x,
|
||||
gint y);
|
||||
extern void poke (gint x,
|
||||
gint y,
|
||||
PikaRGB *color,
|
||||
gpointer user_data);
|
||||
extern PikaVector3 int_to_pos (gint x,
|
||||
gint y);
|
||||
extern void pos_to_int (gdouble x,
|
||||
gdouble y,
|
||||
gint *scr_x,
|
||||
gint *scr_y);
|
||||
|
||||
extern PikaRGB get_image_color (gdouble u,
|
||||
gdouble v,
|
||||
gint *inside);
|
||||
extern PikaRGB get_box_image_color (gint image,
|
||||
gdouble u,
|
||||
gdouble v);
|
||||
extern PikaRGB get_cylinder_image_color (gint image,
|
||||
gdouble u,
|
||||
gdouble v);
|
||||
|
||||
#endif /* __MAPOBJECT_IMAGE_H__ */
|
612
plug-ins/map-object/map-object-main.c
Normal file
612
plug-ins/map-object/map-object-main.c
Normal file
@ -0,0 +1,612 @@
|
||||
/* MapObject 1.2.0 -- image filter plug-in for PIKA
|
||||
*
|
||||
* Copyright (C) 1996-98 Tom Bech
|
||||
* Copyright (C) 1996-98 Federico Mena Quintero
|
||||
*
|
||||
* E-mail: tomb@gimp.org (Tom) or quartic@gimp.org (Federico)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libpika/pika.h>
|
||||
#include <libpika/pikaui.h>
|
||||
|
||||
#include "map-object-ui.h"
|
||||
#include "map-object-image.h"
|
||||
#include "map-object-apply.h"
|
||||
#include "map-object-preview.h"
|
||||
#include "map-object-main.h"
|
||||
|
||||
#include "libpika/stdplugins-intl.h"
|
||||
|
||||
|
||||
MapObjectValues mapvals;
|
||||
|
||||
|
||||
typedef struct _Map Map;
|
||||
typedef struct _MapClass MapClass;
|
||||
|
||||
struct _Map
|
||||
{
|
||||
PikaPlugIn parent_instance;
|
||||
};
|
||||
|
||||
struct _MapClass
|
||||
{
|
||||
PikaPlugInClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
#define MAP_TYPE (map_get_type ())
|
||||
#define MAP (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAP_TYPE, Map))
|
||||
|
||||
GType map_get_type (void) G_GNUC_CONST;
|
||||
|
||||
static GList * map_query_procedures (PikaPlugIn *plug_in);
|
||||
static PikaProcedure * map_create_procedure (PikaPlugIn *plug_in,
|
||||
const gchar *name);
|
||||
|
||||
static PikaValueArray * map_run (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *image,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args,
|
||||
gpointer run_data);
|
||||
|
||||
static void set_default_settings (void);
|
||||
static void check_drawables (PikaDrawable *drawable);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (Map, map, PIKA_TYPE_PLUG_IN)
|
||||
|
||||
PIKA_MAIN (MAP_TYPE)
|
||||
DEFINE_STD_SET_I18N
|
||||
|
||||
|
||||
static void
|
||||
map_class_init (MapClass *klass)
|
||||
{
|
||||
PikaPlugInClass *plug_in_class = PIKA_PLUG_IN_CLASS (klass);
|
||||
|
||||
plug_in_class->query_procedures = map_query_procedures;
|
||||
plug_in_class->create_procedure = map_create_procedure;
|
||||
plug_in_class->set_i18n = STD_SET_I18N;
|
||||
}
|
||||
|
||||
static void
|
||||
map_init (Map *map)
|
||||
{
|
||||
}
|
||||
|
||||
static GList *
|
||||
map_query_procedures (PikaPlugIn *plug_in)
|
||||
{
|
||||
return g_list_append (NULL, g_strdup (PLUG_IN_PROC));
|
||||
}
|
||||
|
||||
static PikaProcedure *
|
||||
map_create_procedure (PikaPlugIn *plug_in,
|
||||
const gchar *name)
|
||||
{
|
||||
PikaProcedure *procedure = NULL;
|
||||
|
||||
if (! strcmp (name, PLUG_IN_PROC))
|
||||
{
|
||||
PikaRGB white = { 1.0, 1.0, 1.0, 1.0 };
|
||||
|
||||
procedure = pika_image_procedure_new (plug_in, name,
|
||||
PIKA_PDB_PROC_TYPE_PLUGIN,
|
||||
map_run, NULL, NULL);
|
||||
|
||||
pika_procedure_set_image_types (procedure, "RGB*");
|
||||
pika_procedure_set_sensitivity_mask (procedure,
|
||||
PIKA_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
pika_procedure_set_menu_label (procedure, _("Map _Object..."));
|
||||
pika_procedure_add_menu_path (procedure, "<Image>/Filters/Map");
|
||||
|
||||
pika_procedure_set_documentation (procedure,
|
||||
_("Map the image to an object "
|
||||
"(plane, sphere, box or cylinder)"),
|
||||
"No help yet",
|
||||
name);
|
||||
pika_procedure_set_attribution (procedure,
|
||||
"Tom Bech & Federico Mena Quintero",
|
||||
"Tom Bech & Federico Mena Quintero",
|
||||
"Version 1.2.0, July 16 1998");
|
||||
|
||||
PIKA_PROC_ARG_INT (procedure, "map-type",
|
||||
"Map type",
|
||||
"Type of mapping (0=plane, 1=sphere, 2=box, "
|
||||
"3=cylinder)",
|
||||
0, 2, MAP_PLANE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "viewpoint-x",
|
||||
"Viewpoint X",
|
||||
"Position of viewpoint (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "viewpoint-y",
|
||||
"Viewpoint Y",
|
||||
"Position of viewpoint (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "viewpoint-z",
|
||||
"Viewpoint Z",
|
||||
"Position of viewpoint (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 2.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "position-x",
|
||||
"Position X",
|
||||
"Object position (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "position-y",
|
||||
"Position Y",
|
||||
"Object position (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "position-z",
|
||||
"Position Z",
|
||||
"Object position (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "first-axis-x",
|
||||
"First axis X",
|
||||
"First axis of object (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "first-axis-y",
|
||||
"First axis y",
|
||||
"First axis of object (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "first-axis-z",
|
||||
"First axis Z",
|
||||
"First axis of object (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "second-axis-x",
|
||||
"Second axis X",
|
||||
"Second axis of object (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "second-axis-y",
|
||||
"Second axis Y",
|
||||
"Second axis of object (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "second-axis-z",
|
||||
"Second axis Z",
|
||||
"Second axis of object (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "rotation-angle-x",
|
||||
"Rotation angle X",
|
||||
"Rotation about X axis in degrees",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "rotation-angle-y",
|
||||
"Rotation angle Y",
|
||||
"Rotation about Y axis in degrees",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "rotation-angle-z",
|
||||
"Rotation angle Z",
|
||||
"Rotation about Z axis in degrees",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_INT (procedure, "light-type",
|
||||
"Light type",
|
||||
"Type of lightsource (0=point, 1=directional, 2=none)",
|
||||
0, 2, POINT_LIGHT,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_RGB (procedure, "light-color",
|
||||
"Light color",
|
||||
"Light source color",
|
||||
TRUE, &white,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "light-position-x",
|
||||
"Light position X",
|
||||
"Light source position (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, -0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "light-position-y",
|
||||
"Light position Y",
|
||||
"Light source position (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, -0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "light-position-z",
|
||||
"Light position Z",
|
||||
"Light source position (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 2.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "light-direction-x",
|
||||
"Light direction X",
|
||||
"Light source direction (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, -1.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "light-direction-y",
|
||||
"Light direction Y",
|
||||
"Light source direction (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, -1.0,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "light-direction-z",
|
||||
"Light direction Z",
|
||||
"Light source direction (x,y,z)",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "ambient-intensity",
|
||||
"Ambient intensity",
|
||||
"Material ambient intensity",
|
||||
0, 1, 0.3,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "diffuse-intensity",
|
||||
"Diffuse intensity",
|
||||
"Material diffuse intensity",
|
||||
0, 1, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "diffuse-reflectivity",
|
||||
"Diffuse reflectivity",
|
||||
"Material diffuse reflectivity",
|
||||
0, 1, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "specular-reflectivity",
|
||||
"Specular reflectivity",
|
||||
"Material specular reflectivity",
|
||||
0, 1, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "highlight",
|
||||
"Highlight",
|
||||
"Material highlight (note, it's exponential)",
|
||||
0, G_MAXDOUBLE, 27.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_BOOLEAN (procedure, "antialiasing",
|
||||
"Antialiasing",
|
||||
"Apply antialiasing",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_BOOLEAN (procedure, "tiled",
|
||||
"Tiled",
|
||||
"Tile source image",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_BOOLEAN (procedure, "new-image",
|
||||
"New image",
|
||||
"Create a new image",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_BOOLEAN (procedure, "transparent-background",
|
||||
"Transparent background",
|
||||
"Make background transparent",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "radius",
|
||||
"Radius",
|
||||
"Sphere/cylinder radius (only used when "
|
||||
"maptype=1 or 3)",
|
||||
0, G_MAXDOUBLE, 0.25,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "x-scale",
|
||||
"X scale",
|
||||
"Box X size",
|
||||
0, G_MAXDOUBLE, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "y-scale",
|
||||
"Y scale",
|
||||
"Box Y size",
|
||||
0, G_MAXDOUBLE, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "z-scale",
|
||||
"Z scale",
|
||||
"Box Z size",
|
||||
0, G_MAXDOUBLE, 0.5,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DOUBLE (procedure, "cylinder-length",
|
||||
"Cylinder length",
|
||||
"Cylinder length",
|
||||
0, G_MAXDOUBLE, 0.25,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "box-front-drawable",
|
||||
"Box front drawable",
|
||||
"Box front face (set these to NULL if not used)",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "box-back-drawable",
|
||||
"Box back drawable",
|
||||
"Box back face",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "box-top-drawable",
|
||||
"Box top drawable",
|
||||
"Box top face",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "box-bottom-drawable",
|
||||
"Box bottom drawable",
|
||||
"Box bottom face",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "box-left-drawable",
|
||||
"Box left drawable",
|
||||
"Box left face",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "box-right-drawable",
|
||||
"Box right drawable",
|
||||
"Box right face",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "cyl-top-drawable",
|
||||
"Cyl top drawable",
|
||||
"Cylinder top face (set these to NULL if not used)",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_DRAWABLE (procedure, "cyl-bottom-drawable",
|
||||
"Cyl bottom drawable",
|
||||
"Cylinder bottom face",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
|
||||
return procedure;
|
||||
}
|
||||
|
||||
static void
|
||||
set_default_settings (void)
|
||||
{
|
||||
gint i;
|
||||
|
||||
pika_vector3_set (&mapvals.viewpoint, 0.5, 0.5, 2.0);
|
||||
pika_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0);
|
||||
pika_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0);
|
||||
pika_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0);
|
||||
pika_vector3_set (&mapvals.position, 0.5, 0.5, 0.0);
|
||||
pika_vector3_set (&mapvals.lightsource.position, -0.5, -0.5, 2.0);
|
||||
pika_vector3_set (&mapvals.lightsource.direction, -1.0, -1.0, 1.0);
|
||||
pika_vector3_set (&mapvals.scale, 0.5, 0.5, 0.5);
|
||||
|
||||
mapvals.maptype = MAP_PLANE;
|
||||
|
||||
mapvals.pixelthreshold = 0.25;
|
||||
mapvals.alpha = 0.0;
|
||||
mapvals.beta = 0.0;
|
||||
mapvals.gamma = 0.0;
|
||||
mapvals.maxdepth = 3.0;
|
||||
mapvals.radius = 0.25;
|
||||
mapvals.cylinder_radius = 0.25;
|
||||
mapvals.cylinder_length = 1.0;
|
||||
|
||||
mapvals.zoom = 1.0;
|
||||
mapvals.lightsource.type = POINT_LIGHT;
|
||||
|
||||
mapvals.antialiasing = TRUE;
|
||||
mapvals.create_new_image = FALSE;
|
||||
mapvals.create_new_layer = FALSE;
|
||||
mapvals.transparent_background = FALSE;
|
||||
mapvals.tiled = FALSE;
|
||||
mapvals.livepreview = FALSE;
|
||||
mapvals.showgrid = TRUE;
|
||||
|
||||
mapvals.lightsource.intensity = 1.0;
|
||||
pika_rgba_set (&mapvals.lightsource.color, 1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
mapvals.material.ambient_int = 0.3;
|
||||
mapvals.material.diffuse_int = 1.0;
|
||||
mapvals.material.diffuse_ref = 0.5;
|
||||
mapvals.material.specular_ref = 0.5;
|
||||
mapvals.material.highlight = 27.0;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
mapvals.boxmap_id[i] = -1;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
mapvals.cylindermap_id[i] = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
check_drawables (PikaDrawable *drawable)
|
||||
{
|
||||
PikaDrawable *map;
|
||||
gint i;
|
||||
|
||||
/* Check that boxmap images are valid */
|
||||
/* ================================== */
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
map = pika_drawable_get_by_id (mapvals.boxmap_id[i]);
|
||||
|
||||
if (! map || pika_drawable_is_gray (map))
|
||||
mapvals.boxmap_id[i] = pika_item_get_id (PIKA_ITEM (drawable));
|
||||
}
|
||||
|
||||
/* Check that cylindermap images are valid */
|
||||
/* ======================================= */
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
map = pika_drawable_get_by_id (mapvals.cylindermap_id[i]);
|
||||
|
||||
if (! map || pika_drawable_is_gray (map))
|
||||
mapvals.cylindermap_id[i] = pika_item_get_id (PIKA_ITEM (drawable));
|
||||
}
|
||||
}
|
||||
|
||||
static PikaValueArray *
|
||||
map_run (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *_image,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args,
|
||||
gpointer run_data)
|
||||
{
|
||||
PikaDrawable *drawable;
|
||||
gint i;
|
||||
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
image = _image;
|
||||
|
||||
if (n_drawables != 1)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_error (&error, PIKA_PLUG_IN_ERROR, 0,
|
||||
_("Procedure '%s' only works with one drawable."),
|
||||
pika_procedure_get_name (procedure));
|
||||
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_CALLING_ERROR,
|
||||
error);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawable = drawables[0];
|
||||
}
|
||||
|
||||
set_default_settings ();
|
||||
|
||||
switch (run_mode)
|
||||
{
|
||||
case PIKA_RUN_INTERACTIVE:
|
||||
pika_get_data (PLUG_IN_PROC, &mapvals);
|
||||
check_drawables (drawable);
|
||||
|
||||
if (! main_dialog (drawable))
|
||||
{
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_CANCEL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
compute_image ();
|
||||
|
||||
pika_set_data (PLUG_IN_PROC, &mapvals, sizeof (MapObjectValues));
|
||||
break;
|
||||
|
||||
case PIKA_RUN_WITH_LAST_VALS:
|
||||
pika_get_data (PLUG_IN_PROC, &mapvals);
|
||||
check_drawables (drawable);
|
||||
|
||||
if (! image_setup (drawable, FALSE))
|
||||
{
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_SUCCESS,
|
||||
NULL);
|
||||
}
|
||||
|
||||
compute_image ();
|
||||
break;
|
||||
|
||||
case PIKA_RUN_NONINTERACTIVE:
|
||||
mapvals.maptype = PIKA_VALUES_GET_INT (args, 0);
|
||||
mapvals.viewpoint.x = PIKA_VALUES_GET_DOUBLE (args, 1);
|
||||
mapvals.viewpoint.y = PIKA_VALUES_GET_DOUBLE (args, 2);
|
||||
mapvals.viewpoint.z = PIKA_VALUES_GET_DOUBLE (args, 3);
|
||||
mapvals.position.x = PIKA_VALUES_GET_DOUBLE (args, 4);
|
||||
mapvals.position.y = PIKA_VALUES_GET_DOUBLE (args, 5);
|
||||
mapvals.position.z = PIKA_VALUES_GET_DOUBLE (args, 6);
|
||||
mapvals.firstaxis.x = PIKA_VALUES_GET_DOUBLE (args, 7);
|
||||
mapvals.firstaxis.y = PIKA_VALUES_GET_DOUBLE (args, 8);
|
||||
mapvals.firstaxis.z = PIKA_VALUES_GET_DOUBLE (args, 9);
|
||||
mapvals.secondaxis.x = PIKA_VALUES_GET_DOUBLE (args, 10);
|
||||
mapvals.secondaxis.y = PIKA_VALUES_GET_DOUBLE (args, 11);
|
||||
mapvals.secondaxis.z = PIKA_VALUES_GET_DOUBLE (args, 12);
|
||||
mapvals.alpha = PIKA_VALUES_GET_DOUBLE (args, 13);
|
||||
mapvals.beta = PIKA_VALUES_GET_DOUBLE (args, 14);
|
||||
mapvals.gamma = PIKA_VALUES_GET_DOUBLE (args, 15);
|
||||
mapvals.lightsource.type = PIKA_VALUES_GET_INT (args, 16);
|
||||
|
||||
PIKA_VALUES_GET_RGB (args, 17, &mapvals.lightsource.color);
|
||||
|
||||
mapvals.lightsource.position.x = PIKA_VALUES_GET_DOUBLE (args, 18);
|
||||
mapvals.lightsource.position.y = PIKA_VALUES_GET_DOUBLE (args, 19);
|
||||
mapvals.lightsource.position.z = PIKA_VALUES_GET_DOUBLE (args, 20);
|
||||
mapvals.lightsource.direction.x = PIKA_VALUES_GET_DOUBLE (args, 21);
|
||||
mapvals.lightsource.direction.y = PIKA_VALUES_GET_DOUBLE (args, 22);
|
||||
mapvals.lightsource.direction.z = PIKA_VALUES_GET_DOUBLE (args, 23);
|
||||
mapvals.material.ambient_int = PIKA_VALUES_GET_DOUBLE (args, 24);
|
||||
mapvals.material.diffuse_int = PIKA_VALUES_GET_DOUBLE (args, 25);
|
||||
mapvals.material.diffuse_ref = PIKA_VALUES_GET_DOUBLE (args, 26);
|
||||
mapvals.material.specular_ref = PIKA_VALUES_GET_DOUBLE (args, 27);
|
||||
mapvals.material.highlight = PIKA_VALUES_GET_DOUBLE (args, 28);
|
||||
mapvals.antialiasing = PIKA_VALUES_GET_BOOLEAN (args, 29);
|
||||
mapvals.tiled = PIKA_VALUES_GET_BOOLEAN (args, 30);
|
||||
mapvals.create_new_image = PIKA_VALUES_GET_BOOLEAN (args, 31);
|
||||
mapvals.transparent_background = PIKA_VALUES_GET_BOOLEAN (args, 32);
|
||||
mapvals.radius =
|
||||
mapvals.cylinder_radius = PIKA_VALUES_GET_DOUBLE (args, 33);
|
||||
mapvals.scale.x = PIKA_VALUES_GET_DOUBLE (args, 34);
|
||||
mapvals.scale.y = PIKA_VALUES_GET_DOUBLE (args, 35);
|
||||
mapvals.scale.z = PIKA_VALUES_GET_DOUBLE (args, 36);
|
||||
mapvals.cylinder_length = PIKA_VALUES_GET_DOUBLE (args, 37);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
mapvals.boxmap_id[i] = PIKA_VALUES_GET_DRAWABLE_ID (args, 38 + i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
mapvals.cylindermap_id[i] = PIKA_VALUES_GET_DRAWABLE_ID (args, 44 + i);
|
||||
}
|
||||
|
||||
check_drawables (drawable);
|
||||
|
||||
if (! image_setup (drawable, FALSE))
|
||||
{
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_SUCCESS,
|
||||
NULL);
|
||||
}
|
||||
|
||||
compute_image ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (run_mode != PIKA_RUN_NONINTERACTIVE)
|
||||
pika_displays_flush ();
|
||||
|
||||
return pika_procedure_new_return_values (procedure, PIKA_PDB_SUCCESS, NULL);
|
||||
}
|
90
plug-ins/map-object/map-object-main.h
Normal file
90
plug-ins/map-object/map-object-main.h
Normal file
@ -0,0 +1,90 @@
|
||||
#ifndef __MAPOBJECT_MAIN_H__
|
||||
#define __MAPOBJECT_MAIN_H__
|
||||
|
||||
/* Defines and stuff */
|
||||
/* ================= */
|
||||
|
||||
#define PLUG_IN_PROC "plug-in-map-object"
|
||||
#define PLUG_IN_BINARY "map-object"
|
||||
#define PLUG_IN_ROLE "pika-map-object"
|
||||
|
||||
#define TILE_CACHE_SIZE 16
|
||||
|
||||
/* Typedefs */
|
||||
/* ======== */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POINT_LIGHT,
|
||||
DIRECTIONAL_LIGHT,
|
||||
NO_LIGHT
|
||||
} LightType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MAP_PLANE,
|
||||
MAP_SPHERE,
|
||||
MAP_BOX,
|
||||
MAP_CYLINDER
|
||||
} MapType;
|
||||
|
||||
/* Typedefs */
|
||||
/* ======== */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gdouble ambient_int;
|
||||
gdouble diffuse_int;
|
||||
gdouble diffuse_ref;
|
||||
gdouble specular_ref;
|
||||
gdouble highlight;
|
||||
PikaRGB color;
|
||||
} MaterialSettings;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LightType type;
|
||||
PikaVector3 position;
|
||||
PikaVector3 direction;
|
||||
PikaRGB color;
|
||||
gdouble intensity;
|
||||
} LightSettings;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PikaVector3 viewpoint,firstaxis,secondaxis,normal,position,scale;
|
||||
LightSettings lightsource;
|
||||
|
||||
MaterialSettings material;
|
||||
MaterialSettings refmaterial;
|
||||
|
||||
MapType maptype;
|
||||
|
||||
gint antialiasing;
|
||||
gint create_new_image;
|
||||
gint create_new_layer;
|
||||
gint transparent_background;
|
||||
gint tiled;
|
||||
gint livepreview;
|
||||
gint showgrid;
|
||||
gint showcaps;
|
||||
|
||||
gdouble zoom;
|
||||
gdouble alpha,beta,gamma;
|
||||
gdouble maxdepth;
|
||||
gdouble pixelthreshold;
|
||||
gdouble radius;
|
||||
gdouble cylinder_radius;
|
||||
gdouble cylinder_length;
|
||||
|
||||
gint32 boxmap_id[6];
|
||||
gint32 cylindermap_id[2];
|
||||
|
||||
} MapObjectValues;
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern MapObjectValues mapvals;
|
||||
|
||||
#endif /* __MAPOBJECT_MAIN_H__ */
|
741
plug-ins/map-object/map-object-preview.c
Normal file
741
plug-ins/map-object/map-object-preview.c
Normal file
@ -0,0 +1,741 @@
|
||||
/*************************************************/
|
||||
/* Compute a preview image and preview wireframe */
|
||||
/*************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libpika/pika.h>
|
||||
#include <libpika/pikaui.h>
|
||||
|
||||
#include "map-object-main.h"
|
||||
#include "map-object-ui.h"
|
||||
#include "map-object-image.h"
|
||||
#include "map-object-apply.h"
|
||||
#include "map-object-shade.h"
|
||||
#include "map-object-preview.h"
|
||||
|
||||
|
||||
gdouble mat[3][4];
|
||||
gint lightx, lighty;
|
||||
|
||||
/* Protos */
|
||||
/* ====== */
|
||||
|
||||
static void compute_preview (gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h,
|
||||
gint pw,
|
||||
gint ph);
|
||||
static void draw_light_marker (cairo_t *cr,
|
||||
gint xpos,
|
||||
gint ypos);
|
||||
static void draw_line (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph,
|
||||
gdouble cx1,
|
||||
gdouble cy1,
|
||||
gdouble cx2,
|
||||
gdouble cy2,
|
||||
PikaVector3 a,
|
||||
PikaVector3 b);
|
||||
static void draw_wireframe (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph);
|
||||
static void draw_preview_wireframe (cairo_t *cr);
|
||||
static void draw_wireframe_plane (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph);
|
||||
static void draw_wireframe_sphere (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph);
|
||||
static void draw_wireframe_box (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph);
|
||||
static void draw_wireframe_cylinder (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph);
|
||||
|
||||
/**************************************************************/
|
||||
/* Computes a preview of the rectangle starting at (x,y) with */
|
||||
/* dimensions (w,h), placing the result in preview_RGB_data. */
|
||||
/**************************************************************/
|
||||
|
||||
static void
|
||||
compute_preview (gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h,
|
||||
gint pw,
|
||||
gint ph)
|
||||
{
|
||||
gdouble xpostab[PREVIEW_WIDTH];
|
||||
gdouble ypostab[PREVIEW_HEIGHT];
|
||||
gdouble realw;
|
||||
gdouble realh;
|
||||
PikaVector3 p1, p2;
|
||||
PikaRGB color;
|
||||
PikaRGB lightcheck, darkcheck;
|
||||
gint xcnt, ycnt, f1, f2;
|
||||
guchar r, g, b;
|
||||
glong index = 0;
|
||||
|
||||
init_compute ();
|
||||
|
||||
if (! preview_surface)
|
||||
return;
|
||||
|
||||
p1 = int_to_pos (x, y);
|
||||
p2 = int_to_pos (x + w, y + h);
|
||||
|
||||
/* First, compute the linear mapping (x,y,x+w,y+h) to (0,0,pw,ph) */
|
||||
/* ============================================================== */
|
||||
|
||||
realw = (p2.x - p1.x);
|
||||
realh = (p2.y - p1.y);
|
||||
|
||||
for (xcnt = 0; xcnt < pw; xcnt++)
|
||||
xpostab[xcnt] = p1.x + realw * ((gdouble) xcnt / (gdouble) pw);
|
||||
|
||||
for (ycnt = 0; ycnt < ph; ycnt++)
|
||||
ypostab[ycnt] = p1.y + realh * ((gdouble) ycnt / (gdouble) ph);
|
||||
|
||||
/* Compute preview using the offset tables */
|
||||
/* ======================================= */
|
||||
|
||||
if (mapvals.transparent_background == TRUE)
|
||||
{
|
||||
pika_rgba_set (&background, 0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pika_context_get_background (&background);
|
||||
pika_rgb_set_alpha (&background, 1.0);
|
||||
}
|
||||
|
||||
pika_rgba_set (&lightcheck,
|
||||
PIKA_CHECK_LIGHT, PIKA_CHECK_LIGHT, PIKA_CHECK_LIGHT, 1.0);
|
||||
pika_rgba_set (&darkcheck,
|
||||
PIKA_CHECK_DARK, PIKA_CHECK_DARK, PIKA_CHECK_DARK, 1.0);
|
||||
pika_vector3_set (&p2, -1.0, -1.0, 0.0);
|
||||
|
||||
cairo_surface_flush (preview_surface);
|
||||
|
||||
for (ycnt = 0; ycnt < ph; ycnt++)
|
||||
{
|
||||
index = ycnt * preview_rgb_stride;
|
||||
for (xcnt = 0; xcnt < pw; xcnt++)
|
||||
{
|
||||
p1.x = xpostab[xcnt];
|
||||
p1.y = ypostab[ycnt];
|
||||
|
||||
p2 = p1;
|
||||
color = (* get_ray_color) (&p1);
|
||||
|
||||
if (color.a < 1.0)
|
||||
{
|
||||
f1 = ((xcnt % 32) < 16);
|
||||
f2 = ((ycnt % 32) < 16);
|
||||
f1 = f1 ^ f2;
|
||||
|
||||
if (f1)
|
||||
{
|
||||
if (color.a == 0.0)
|
||||
color = lightcheck;
|
||||
else
|
||||
pika_rgb_composite (&color, &lightcheck,
|
||||
PIKA_RGB_COMPOSITE_BEHIND);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (color.a == 0.0)
|
||||
color = darkcheck;
|
||||
else
|
||||
pika_rgb_composite (&color, &darkcheck,
|
||||
PIKA_RGB_COMPOSITE_BEHIND);
|
||||
}
|
||||
}
|
||||
|
||||
pika_rgb_get_uchar (&color, &r, &g, &b);
|
||||
PIKA_CAIRO_RGB24_SET_PIXEL((preview_rgb_data + index), r, g, b);
|
||||
index += 4;
|
||||
}
|
||||
}
|
||||
cairo_surface_mark_dirty (preview_surface);
|
||||
}
|
||||
|
||||
/*************************************************/
|
||||
/* Check if the given position is within the */
|
||||
/* light marker. Return TRUE if so, FALSE if not */
|
||||
/*************************************************/
|
||||
|
||||
gint
|
||||
check_light_hit (gint xpos,
|
||||
gint ypos)
|
||||
{
|
||||
gdouble dx, dy, r;
|
||||
|
||||
if (mapvals.lightsource.type == POINT_LIGHT)
|
||||
{
|
||||
dx = (gdouble) lightx - xpos;
|
||||
dy = (gdouble) lighty - ypos;
|
||||
r = sqrt (dx * dx + dy * dy) + 0.5;
|
||||
|
||||
if ((gint) r > 7)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Draw a marker to show light position */
|
||||
/****************************************/
|
||||
|
||||
static void
|
||||
draw_light_marker (cairo_t *cr,
|
||||
gint xpos,
|
||||
gint ypos)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
if (mapvals.lightsource.type != POINT_LIGHT)
|
||||
return;
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
|
||||
color.red = 0.0;
|
||||
color.green = 0.2;
|
||||
color.blue = 1.0;
|
||||
color.alpha = 1.0;
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
|
||||
lightx = xpos;
|
||||
lighty = ypos;
|
||||
|
||||
cairo_arc (cr, lightx, lighty, 7, 0, 2 * G_PI);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_lights (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph)
|
||||
{
|
||||
gdouble dxpos, dypos;
|
||||
gint xpos, ypos;
|
||||
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&dxpos, &dypos, &mapvals.viewpoint,
|
||||
&mapvals.lightsource.position);
|
||||
xpos = RINT (dxpos);
|
||||
ypos = RINT (dypos);
|
||||
|
||||
if (xpos >= 0 && xpos <= PREVIEW_WIDTH &&
|
||||
ypos >= 0 && ypos <= PREVIEW_HEIGHT)
|
||||
{
|
||||
draw_light_marker (cr, xpos, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************/
|
||||
/* Update light position given new screen coords */
|
||||
/*************************************************/
|
||||
|
||||
void
|
||||
update_light (gint xpos,
|
||||
gint ypos)
|
||||
{
|
||||
gint startx, starty, pw, ph;
|
||||
|
||||
pw = PREVIEW_WIDTH * mapvals.zoom;
|
||||
ph = PREVIEW_HEIGHT * mapvals.zoom;
|
||||
startx = (PREVIEW_WIDTH - pw) / 2;
|
||||
starty = (PREVIEW_HEIGHT - ph) / 2;
|
||||
|
||||
pika_vector_2d_to_3d (startx, starty, pw, ph, xpos, ypos,
|
||||
&mapvals.viewpoint, &mapvals.lightsource.position);
|
||||
|
||||
gtk_widget_queue_draw (previewarea);
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Compute preview image. */
|
||||
/**************************/
|
||||
|
||||
void
|
||||
compute_preview_image (void)
|
||||
{
|
||||
GdkDisplay *display = gtk_widget_get_display (previewarea);
|
||||
GdkCursor *cursor;
|
||||
gint pw, ph;
|
||||
|
||||
pw = PREVIEW_WIDTH * mapvals.zoom;
|
||||
ph = PREVIEW_HEIGHT * mapvals.zoom;
|
||||
|
||||
cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
|
||||
gdk_window_set_cursor (gtk_widget_get_window (previewarea), cursor);
|
||||
g_object_unref (cursor);
|
||||
|
||||
compute_preview (0, 0, width - 1, height - 1, pw, ph);
|
||||
|
||||
cursor = gdk_cursor_new_for_display (display, GDK_HAND2);
|
||||
gdk_window_set_cursor(gtk_widget_get_window (previewarea), cursor);
|
||||
g_object_unref (cursor);
|
||||
}
|
||||
|
||||
gboolean
|
||||
preview_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
gint startx, starty, pw, ph;
|
||||
|
||||
pw = PREVIEW_WIDTH * mapvals.zoom;
|
||||
ph = PREVIEW_HEIGHT * mapvals.zoom;
|
||||
startx = (PREVIEW_WIDTH - pw) / 2;
|
||||
starty = (PREVIEW_HEIGHT - ph) / 2;
|
||||
|
||||
cairo_set_source_surface (cr, preview_surface, startx, starty);
|
||||
cairo_rectangle (cr, startx, starty, pw, ph);
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_reset_clip (cr);
|
||||
|
||||
if (mapvals.showgrid)
|
||||
draw_preview_wireframe (cr);
|
||||
|
||||
cairo_reset_clip (cr);
|
||||
draw_lights (cr, startx, starty, pw, ph);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Draw preview wireframe */
|
||||
/**************************/
|
||||
|
||||
void
|
||||
draw_preview_wireframe (cairo_t *cr)
|
||||
{
|
||||
gint startx, starty, pw, ph;
|
||||
|
||||
pw = PREVIEW_WIDTH * mapvals.zoom;
|
||||
ph = PREVIEW_HEIGHT * mapvals.zoom;
|
||||
startx = (PREVIEW_WIDTH - pw) / 2;
|
||||
starty = (PREVIEW_HEIGHT - ph) / 2;
|
||||
|
||||
draw_wireframe (cr, startx, starty, pw, ph);
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* Draw a wireframe preview */
|
||||
/****************************/
|
||||
|
||||
void
|
||||
draw_wireframe (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph)
|
||||
{
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
|
||||
switch (mapvals.maptype)
|
||||
{
|
||||
case MAP_PLANE:
|
||||
draw_wireframe_plane (cr, startx, starty, pw, ph);
|
||||
break;
|
||||
case MAP_SPHERE:
|
||||
draw_wireframe_sphere (cr, startx, starty, pw, ph);
|
||||
break;
|
||||
case MAP_BOX:
|
||||
draw_wireframe_box (cr, startx, starty, pw, ph);
|
||||
break;
|
||||
case MAP_CYLINDER:
|
||||
draw_wireframe_cylinder (cr, startx, starty, pw, ph);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_wireframe_plane (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph)
|
||||
{
|
||||
PikaVector3 v1, v2, a, b, c, d, dir1, dir2;
|
||||
gint cnt;
|
||||
gdouble x1, y1, x2, y2, fac;
|
||||
|
||||
cairo_rectangle (cr, startx, starty, pw, ph);
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Find rotated box corners */
|
||||
/* ======================== */
|
||||
|
||||
pika_vector3_set (&v1, 0.5, 0.0, 0.0);
|
||||
pika_vector3_set (&v2, 0.0, 0.5, 0.0);
|
||||
|
||||
pika_vector3_rotate (&v1,
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
|
||||
pika_vector3_rotate (&v2,
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
|
||||
dir1 = v1; pika_vector3_normalize (&dir1);
|
||||
dir2 = v2; pika_vector3_normalize (&dir2);
|
||||
|
||||
fac = 1.0 / (gdouble) WIRESIZE;
|
||||
|
||||
pika_vector3_mul (&dir1, fac);
|
||||
pika_vector3_mul (&dir2, fac);
|
||||
|
||||
pika_vector3_add (&a, &mapvals.position, &v1);
|
||||
pika_vector3_sub (&b, &a, &v2);
|
||||
pika_vector3_add (&a, &a, &v2);
|
||||
pika_vector3_sub (&d, &mapvals.position, &v1);
|
||||
pika_vector3_sub (&d, &d, &v2);
|
||||
|
||||
c = b;
|
||||
|
||||
for (cnt = 0; cnt <= WIRESIZE; cnt++)
|
||||
{
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x1, &y1, &mapvals.viewpoint, &a);
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x2, &y2, &mapvals.viewpoint, &b);
|
||||
|
||||
cairo_move_to (cr, RINT (x1) + 0.5, RINT (y1) + 0.5);
|
||||
cairo_line_to (cr, RINT (x2) + 0.5, RINT (y2) + 0.5);
|
||||
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x1, &y1, &mapvals.viewpoint, &c);
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x2, &y2, &mapvals.viewpoint, &d);
|
||||
|
||||
cairo_move_to (cr, RINT (x1) + 0.5, RINT (y1) + 0.5);
|
||||
cairo_line_to (cr, RINT (x2) + 0.5, RINT (y2) + 0.5);
|
||||
|
||||
pika_vector3_sub (&a, &a, &dir1);
|
||||
pika_vector3_sub (&b, &b, &dir1);
|
||||
pika_vector3_add (&c, &c, &dir2);
|
||||
pika_vector3_add (&d, &d, &dir2);
|
||||
}
|
||||
|
||||
cairo_set_line_width (cr, 3.0);
|
||||
cairo_stroke_preserve (cr);
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_wireframe_sphere (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph)
|
||||
{
|
||||
PikaVector3 p[2 * (WIRESIZE + 5)];
|
||||
gint cnt, cnt2;
|
||||
gdouble x1, y1, x2, y2, twopifac;
|
||||
|
||||
cairo_rectangle (cr, startx, starty, pw, ph);
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Compute wireframe points */
|
||||
/* ======================== */
|
||||
|
||||
twopifac = (2.0 * G_PI) / WIRESIZE;
|
||||
|
||||
for (cnt = 0; cnt < WIRESIZE; cnt++)
|
||||
{
|
||||
p[cnt].x = mapvals.radius * cos ((gdouble) cnt * twopifac);
|
||||
p[cnt].y = 0.0;
|
||||
p[cnt].z = mapvals.radius * sin ((gdouble) cnt * twopifac);
|
||||
pika_vector3_rotate (&p[cnt],
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
pika_vector3_add (&p[cnt], &p[cnt], &mapvals.position);
|
||||
}
|
||||
|
||||
p[cnt] = p[0];
|
||||
|
||||
for (cnt = WIRESIZE + 1; cnt < 2 * WIRESIZE + 1; cnt++)
|
||||
{
|
||||
p[cnt].x = mapvals.radius * cos ((gdouble) (cnt-(WIRESIZE+1))*twopifac);
|
||||
p[cnt].y = mapvals.radius * sin ((gdouble) (cnt-(WIRESIZE+1))*twopifac);
|
||||
p[cnt].z = 0.0;
|
||||
pika_vector3_rotate (&p[cnt],
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
pika_vector3_add (&p[cnt], &p[cnt], &mapvals.position);
|
||||
}
|
||||
|
||||
p[cnt] = p[WIRESIZE+1];
|
||||
cnt++;
|
||||
cnt2 = cnt;
|
||||
|
||||
/* Find rotated axis */
|
||||
/* ================= */
|
||||
|
||||
pika_vector3_set (&p[cnt], 0.0, -0.35, 0.0);
|
||||
pika_vector3_rotate (&p[cnt],
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
p[cnt+1] = mapvals.position;
|
||||
|
||||
pika_vector3_set (&p[cnt+2], 0.0, 0.0, -0.35);
|
||||
pika_vector3_rotate (&p[cnt+2],
|
||||
pika_deg_to_rad (mapvals.alpha),
|
||||
pika_deg_to_rad (mapvals.beta),
|
||||
pika_deg_to_rad (mapvals.gamma));
|
||||
p[cnt+3] = mapvals.position;
|
||||
|
||||
p[cnt + 4] = p[cnt];
|
||||
pika_vector3_mul (&p[cnt + 4], -1.0);
|
||||
p[cnt + 5] = p[cnt + 1];
|
||||
|
||||
pika_vector3_add (&p[cnt], &p[cnt], &mapvals.position);
|
||||
pika_vector3_add (&p[cnt + 2], &p[cnt + 2], &mapvals.position);
|
||||
pika_vector3_add (&p[cnt + 4], &p[cnt + 4], &mapvals.position);
|
||||
|
||||
/* Draw the circles (equator and zero meridian) */
|
||||
/* ============================================ */
|
||||
|
||||
for (cnt = 0; cnt < cnt2 - 1; cnt++)
|
||||
{
|
||||
if (p[cnt].z > mapvals.position.z && p[cnt + 1].z > mapvals.position.z)
|
||||
{
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x1, &y1, &mapvals.viewpoint, &p[cnt]);
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x2, &y2, &mapvals.viewpoint, &p[cnt + 1]);
|
||||
|
||||
cairo_move_to (cr, (gint) (x1 + 0.5) + 0.5, (gint) (y1 + 0.5) + 0.5);
|
||||
cairo_line_to (cr, (gint) (x2 + 0.5) + 0.5, (gint) (y2 + 0.5) + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the axis (pole to pole and center to zero meridian) */
|
||||
/* ======================================================== */
|
||||
|
||||
for (cnt = 0; cnt < 3; cnt++)
|
||||
{
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x1, &y1, &mapvals.viewpoint, &p[cnt2]);
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x2, &y2, &mapvals.viewpoint, &p[cnt2 + 1]);
|
||||
|
||||
cairo_move_to (cr, RINT (x1) + 0.5, RINT (y1) + 0.5);
|
||||
cairo_line_to (cr, RINT (x2) + 0.5, RINT (y2) + 0.5);
|
||||
|
||||
cnt2 += 2;
|
||||
}
|
||||
|
||||
cairo_set_line_width (cr, 3.0);
|
||||
cairo_stroke_preserve (cr);
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_line (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph,
|
||||
gdouble cx1,
|
||||
gdouble cy1,
|
||||
gdouble cx2,
|
||||
gdouble cy2,
|
||||
PikaVector3 a,
|
||||
PikaVector3 b)
|
||||
{
|
||||
gdouble x1, y1, x2, y2;
|
||||
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x1, &y1, &mapvals.viewpoint, &a);
|
||||
pika_vector_3d_to_2d (startx, starty, pw, ph,
|
||||
&x2, &y2, &mapvals.viewpoint, &b);
|
||||
|
||||
cairo_move_to (cr, RINT (x1) + 0.5, RINT (y1) + 0.5);
|
||||
cairo_line_to (cr, RINT (x2) + 0.5, RINT (y2) + 0.5);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_wireframe_box (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph)
|
||||
{
|
||||
PikaVector3 p[8], tmp, scale;
|
||||
gint i;
|
||||
gdouble cx1, cy1, cx2, cy2;
|
||||
|
||||
cairo_rectangle (cr, startx, starty, pw, ph);
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Compute wireframe points */
|
||||
/* ======================== */
|
||||
|
||||
init_compute ();
|
||||
|
||||
scale = mapvals.scale;
|
||||
pika_vector3_mul (&scale, 0.5);
|
||||
|
||||
pika_vector3_set (&p[0], -scale.x, -scale.y, scale.z);
|
||||
pika_vector3_set (&p[1], scale.x, -scale.y, scale.z);
|
||||
pika_vector3_set (&p[2], scale.x, scale.y, scale.z);
|
||||
pika_vector3_set (&p[3], -scale.x, scale.y, scale.z);
|
||||
|
||||
pika_vector3_set (&p[4], -scale.x, -scale.y, -scale.z);
|
||||
pika_vector3_set (&p[5], scale.x, -scale.y, -scale.z);
|
||||
pika_vector3_set (&p[6], scale.x, scale.y, -scale.z);
|
||||
pika_vector3_set (&p[7], -scale.x, scale.y, -scale.z);
|
||||
|
||||
/* Rotate and translate points */
|
||||
/* =========================== */
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
vecmulmat (&tmp, &p[i], rotmat);
|
||||
pika_vector3_add (&p[i], &tmp, &mapvals.position);
|
||||
}
|
||||
|
||||
/* Draw the box */
|
||||
/* ============ */
|
||||
|
||||
cx1 = (gdouble) startx;
|
||||
cy1 = (gdouble) starty;
|
||||
cx2 = cx1 + (gdouble) pw;
|
||||
cy2 = cy1 + (gdouble) ph;
|
||||
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[0],p[1]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[1],p[2]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[2],p[3]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[3],p[0]);
|
||||
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[4],p[5]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[5],p[6]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[6],p[7]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[7],p[4]);
|
||||
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[0],p[4]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[1],p[5]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[2],p[6]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[3],p[7]);
|
||||
|
||||
cairo_set_line_width (cr, 3.0);
|
||||
cairo_stroke_preserve (cr);
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_wireframe_cylinder (cairo_t *cr,
|
||||
gint startx,
|
||||
gint starty,
|
||||
gint pw,
|
||||
gint ph)
|
||||
{
|
||||
PikaVector3 p[2*8], a, axis, scale;
|
||||
gint i;
|
||||
gdouble cx1, cy1, cx2, cy2;
|
||||
gfloat m[16], l, angle;
|
||||
|
||||
cairo_rectangle (cr, startx, starty, pw, ph);
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Compute wireframe points */
|
||||
/* ======================== */
|
||||
|
||||
init_compute ();
|
||||
|
||||
scale = mapvals.scale;
|
||||
pika_vector3_mul (&scale, 0.5);
|
||||
|
||||
l = mapvals.cylinder_length / 2.0;
|
||||
angle = 0;
|
||||
|
||||
pika_vector3_set (&axis, 0.0, 1.0, 0.0);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
rotatemat (angle, &axis, m);
|
||||
|
||||
pika_vector3_set (&a, mapvals.cylinder_radius, 0.0, 0.0);
|
||||
|
||||
vecmulmat (&p[i], &a, m);
|
||||
|
||||
p[i+8] = p[i];
|
||||
|
||||
p[i].y += l;
|
||||
p[i+8].y -= l;
|
||||
|
||||
angle += 360.0 / 8.0;
|
||||
}
|
||||
|
||||
/* Rotate and translate points */
|
||||
/* =========================== */
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
vecmulmat (&a, &p[i], rotmat);
|
||||
pika_vector3_add (&p[i], &a, &mapvals.position);
|
||||
}
|
||||
|
||||
/* Draw the box */
|
||||
/* ============ */
|
||||
|
||||
cx1 = (gdouble) startx;
|
||||
cy1 = (gdouble) starty;
|
||||
cx2 = cx1 + (gdouble) pw;
|
||||
cy2 = cy1 + (gdouble) ph;
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i],p[i+1]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i+8],p[i+9]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i],p[i+8]);
|
||||
}
|
||||
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[7],p[0]);
|
||||
draw_line (cr, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[15],p[8]);
|
||||
|
||||
cairo_set_line_width (cr, 3.0);
|
||||
cairo_stroke_preserve (cr);
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||||
cairo_stroke (cr);
|
||||
}
|
26
plug-ins/map-object/map-object-preview.h
Normal file
26
plug-ins/map-object/map-object-preview.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef __MAPOBJECT_PREVIEW_H__
|
||||
#define __MAPOBJECT_PREVIEW_H__
|
||||
|
||||
#define PREVIEW_WIDTH 200
|
||||
#define PREVIEW_HEIGHT 200
|
||||
|
||||
#define WIRESIZE 16
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern gdouble mat[3][4];
|
||||
extern gint lightx,lighty;
|
||||
|
||||
/* Externally visible functions */
|
||||
/* ============================ */
|
||||
|
||||
void compute_preview_image (void);
|
||||
gboolean preview_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
gint check_light_hit (gint xpos,
|
||||
gint ypos);
|
||||
void update_light (gint xpos,
|
||||
gint ypos);
|
||||
|
||||
#endif /* __MAPOBJECT_PREVIEW_H__ */
|
1254
plug-ins/map-object/map-object-shade.c
Normal file
1254
plug-ins/map-object/map-object-shade.c
Normal file
File diff suppressed because it is too large
Load Diff
26
plug-ins/map-object/map-object-shade.h
Normal file
26
plug-ins/map-object/map-object-shade.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef __MAPOBJECT_SHADE_H__
|
||||
#define __MAPOBJECT_SHADE_H__
|
||||
|
||||
typedef PikaRGB (* get_ray_color_func) (PikaVector3 *pos);
|
||||
|
||||
extern get_ray_color_func get_ray_color;
|
||||
|
||||
PikaRGB get_ray_color_plane (PikaVector3 *pos);
|
||||
PikaRGB get_ray_color_sphere (PikaVector3 *pos);
|
||||
PikaRGB get_ray_color_box (PikaVector3 *pos);
|
||||
PikaRGB get_ray_color_cylinder (PikaVector3 *pos);
|
||||
void compute_bounding_box (void);
|
||||
|
||||
void vecmulmat (PikaVector3 *u,
|
||||
PikaVector3 *v,
|
||||
gfloat m[16]);
|
||||
void rotatemat (gfloat angle,
|
||||
PikaVector3 *v,
|
||||
gfloat m[16]);
|
||||
void transpose_mat (gfloat m[16]);
|
||||
void matmul (gfloat a[16],
|
||||
gfloat b[16],
|
||||
gfloat c[16]);
|
||||
void ident_mat (gfloat m[16]);
|
||||
|
||||
#endif /* __MAPOBJECT_SHADE_H__ */
|
1449
plug-ins/map-object/map-object-ui.c
Normal file
1449
plug-ins/map-object/map-object-ui.c
Normal file
File diff suppressed because it is too large
Load Diff
14
plug-ins/map-object/map-object-ui.h
Normal file
14
plug-ins/map-object/map-object-ui.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __MAPOBJECT_UI_H__
|
||||
#define __MAPOBJECT_UI_H__
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern GtkWidget *previewarea;
|
||||
|
||||
/* Externally visible functions */
|
||||
/* ============================ */
|
||||
|
||||
gboolean main_dialog (PikaDrawable *drawable);
|
||||
|
||||
#endif /* __MAPOBJECT_UI_H__ */
|
38
plug-ins/map-object/meson.build
Normal file
38
plug-ins/map-object/meson.build
Normal file
@ -0,0 +1,38 @@
|
||||
plugin_name = 'map-object'
|
||||
|
||||
plugin_sources = [
|
||||
'arcball.c',
|
||||
'map-object-apply.c',
|
||||
'map-object-icons.c',
|
||||
'map-object-image.c',
|
||||
'map-object-main.c',
|
||||
'map-object-preview.c',
|
||||
'map-object-shade.c',
|
||||
'map-object-ui.c',
|
||||
lighting_icon_sources,
|
||||
]
|
||||
|
||||
if platform_windows
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
'--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
'--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
'--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
|
||||
executable(plugin_name,
|
||||
plugin_sources,
|
||||
dependencies: [
|
||||
libpikaui_dep,
|
||||
math,
|
||||
],
|
||||
install: true,
|
||||
install_dir: pikaplugindir / 'plug-ins' / plugin_name,
|
||||
)
|
Reference in New Issue
Block a user