mirror of https://github.com/GNOME/gimp.git
parent
33c01ce52e
commit
a0dfbce3ba
|
@ -0,0 +1,6 @@
|
|||
Makefile.in
|
||||
Makefile
|
||||
.deps
|
||||
_libs
|
||||
.libs
|
||||
MapObject
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
Changes (post 0.31):
|
||||
====================
|
||||
|
||||
-> 0.31 Merged MapPlane and MapSphere. Added support for non-interactive
|
||||
execution (for script-fu).
|
||||
-> 0.32 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.40 Some source/algorithm cleanups, fixed gtk+ object refcounting bugs. Some
|
||||
changes to compile with gtk+ 0.99.4.
|
||||
-> 1.00 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.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pluginlibdir = $(gimpplugindir)/plug-ins
|
||||
|
||||
pluginlib_PROGRAMS = MapObject
|
||||
|
||||
MapObject_SOURCES = \
|
||||
amb1.xpm amb2.xpm arcball.c arcball.h diffint1.xpm diffint2.xpm diffref1.xpm diffref2.xpm high1.xpm high2.xpm mapobject_apply.c mapobject_apply.h mapobject_image.c mapobject_image.h mapobject_main.c mapobject_main.h mapobject_pixmaps.h mapobject_preview.c mapobject_preview.h mapobject_shade.c mapobject_shade.h mapobject_ui.c mapobject_ui.h specref1.xpm specref2.xpm
|
||||
|
||||
INCLUDES = \
|
||||
# -I$(top_srcdir) \
|
||||
-I$(top_srcdir)/libgck \
|
||||
-I$(includedir) \
|
||||
$(X_CFLAGS)
|
||||
|
||||
LDADD = \
|
||||
# $(top_builddir)/libgimp/libgimpui.la \
|
||||
# $(top_builddir)/libgimp/libgimp.la \
|
||||
$(top_builddir)/libgck/gck/libgck.la \
|
||||
$(X_LIBS) \
|
||||
-lc
|
||||
|
||||
DEPS = \
|
||||
# $(top_builddir)/libgimp/libgimpui.la \
|
||||
# $(top_builddir)/libgimp/libgimp.la \
|
||||
$(top_builddir)/libgck/gck/libgck.la
|
||||
|
||||
MapObject_DEPENDENCIES = $(DEPS)
|
||||
|
||||
.PHONY: files
|
||||
|
||||
files:
|
||||
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
|
||||
echo $$p; \
|
||||
done
|
||||
@for subdir in $(SUBDIRS); do \
|
||||
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
|
||||
for file in $$files; do \
|
||||
echo $$subdir/$$file; \
|
||||
done; \
|
||||
done
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
MapObject 1.00 -- image filter plug-in for The GIMP program
|
||||
===========================================================
|
||||
|
||||
Copyright (C) 1996-98 Tom Bech
|
||||
Copyright (C) 1996-98 Federico Mena Quintero
|
||||
|
||||
You can reach the author(s) via E-mail:
|
||||
tomb@gimp.org (Tom) or quartic@gimp.org (Federico).
|
||||
|
||||
The GIMP was developed by Peter Mattis and Spencer Kimball.
|
||||
You can contact them at gimp@xcf.berkeley.edu.
|
||||
|
||||
There's more GIMP stuff on our home pages:
|
||||
http://www.ii.uib.no/~tomb/gimp.html (Tom's page)
|
||||
http://www.nuclecu.unam.mx/~federico/gimp/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 2 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 (see "COPYING" file); if not, write to the Free Software Foundation,
|
||||
Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
In other words, you can't sue us for whatever happens while using this ;)
|
||||
|
||||
Compiling
|
||||
=========
|
||||
|
||||
To compile you'll need The GIMP 0.99.20 and GTK+ 0.99.7 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 "map_object"
|
||||
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
|
|
@ -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 - at least cube and cylinder.
|
||||
* 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
|
|
@ -0,0 +1,88 @@
|
|||
/* XPM */
|
||||
char * amb1_xpm[] = {
|
||||
"32 32 53 1",
|
||||
" c None",
|
||||
". c #861786178617",
|
||||
"X c #861782078617",
|
||||
"o c #69A66DB669A6",
|
||||
"O c #8E388E388E38",
|
||||
"+ c #B6DAB2CAB6DA",
|
||||
"@ c #BEFBBAEABEFB",
|
||||
"# c #AEBAAEBAAEBA",
|
||||
"$ c #9E799E799E79",
|
||||
"% c #8E388A288E38",
|
||||
"& c #618565956185",
|
||||
"* c #30C234D330C2",
|
||||
"= c #A699A699A699",
|
||||
"- c #CF3CCF3CCF3C",
|
||||
"; c #D75CD34CD75C",
|
||||
": c #C71BC30BC71B",
|
||||
"> c #DF7DDF7DDF7D",
|
||||
", c #D75CD75CD75C",
|
||||
"< c #CF3CCB2BCF3C",
|
||||
"1 c #AEBAAAAAAEBA",
|
||||
"2 c #965896589658",
|
||||
"3 c #79E779E779E7",
|
||||
"4 c #514455555144",
|
||||
"5 c #18611C711861",
|
||||
"6 c #E79DE38DE79D",
|
||||
"7 c #E79DE79DE79D",
|
||||
"8 c #DF7DDB6CDF7D",
|
||||
"9 c #BEFBBEFBBEFB",
|
||||
"0 c #9E799A699E79",
|
||||
"q c #79E77DF779E7",
|
||||
"w c #618561856185",
|
||||
"e c #38E338E338E3",
|
||||
"r c #000004100000",
|
||||
"t c #EFBEEFBEEFBE",
|
||||
"y c #FFFFFBEEFFFF",
|
||||
"u c #410341034103",
|
||||
"i c #08200C300820",
|
||||
"p c #FFFFFFFFFFFF",
|
||||
"a c #B6DAB6DAB6DA",
|
||||
"s c #965892489658",
|
||||
"d c #104014511040",
|
||||
"f c #71C675D671C6",
|
||||
"g c #596559655965",
|
||||
"h c #104010401040",
|
||||
"j c #000000000000",
|
||||
"k c #514451445144",
|
||||
"l c #30C230C230C2",
|
||||
"z c #59655D755965",
|
||||
"x c #410345144103",
|
||||
"c c #208124922081",
|
||||
"v c #49244D344924",
|
||||
"b c #208120812081",
|
||||
"n c #082008200820",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .Xo ",
|
||||
" O+@@#$%&* ",
|
||||
" =-;;-:+$.&* ",
|
||||
" =;>>>,<@12345 ",
|
||||
" O->6778-9#0qwer ",
|
||||
" +;>7tyt-910X&ui ",
|
||||
" @;>7ypy-a=sqwud ",
|
||||
" .@-,8ty6:#$Ofgehj ",
|
||||
" X#:<---:+=2Xoklij ",
|
||||
" o$+@99a#=2.fzxcrj ",
|
||||
" %$1#1=$2.f&v*dj ",
|
||||
" &.200sOXf&kebrj ",
|
||||
" *&3qXqfozvecnjj ",
|
||||
" *4w&wgkx*bnjj ",
|
||||
" 5euuelcdrjj ",
|
||||
" ridhirjjj ",
|
||||
" jjj ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,58 @@
|
|||
/* XPM */
|
||||
char * amb2_xpm[] = {
|
||||
"32 32 23 1",
|
||||
" c None",
|
||||
". c #CF3CCF3CCF3C",
|
||||
"X c #CF3CCB2BCF3C",
|
||||
"o c #C71BC30BC71B",
|
||||
"O c #D75CD75CD75C",
|
||||
"+ c #DF7DDB6CDF7D",
|
||||
"@ c #C71BC71BC71B",
|
||||
"# c #AEBAAEBAAEBA",
|
||||
"$ c #DF7DDF7DDF7D",
|
||||
"% c #E79DE38DE79D",
|
||||
"& c #D75CD34CD75C",
|
||||
"* c #E79DE79DE79D",
|
||||
"= c #AEBAAAAAAEBA",
|
||||
"- c #EFBEEBADEFBE",
|
||||
"; c #BEFBBEFBBEFB",
|
||||
": c #A699A289A699",
|
||||
"> c #F7DEF3CEF7DE",
|
||||
", c #F7DEF7DEF7DE",
|
||||
"< c #B6DAB2CAB6DA",
|
||||
"1 c #FFFFFFFFFFFF",
|
||||
"2 c #FFFFFBEEFFFF",
|
||||
"3 c #B6DAB6DAB6DA",
|
||||
"4 c #BEFBBAEABEFB",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ..X ",
|
||||
" oO+++O.@# ",
|
||||
" X$%%$$+O&X# ",
|
||||
" X%%*%%$$+&.@= ",
|
||||
" o$%**-*%$+O.@;: ",
|
||||
" O%**>,,%$+O.Xo< ",
|
||||
" +%%-,12*+O&.Xo3 ",
|
||||
" .+$%*,2,%+O&.@;3< ",
|
||||
" .+$$%%*%+O&.X@;3< ",
|
||||
" XO+$$$++OO&.@o43< ",
|
||||
" .O+++OO&&.Xo;3< ",
|
||||
" @&&OO&&..X@;43# ",
|
||||
" #X.....X@o;43<: ",
|
||||
" #@@XX@@o;43<: ",
|
||||
" =;oo;;433<: ",
|
||||
" :<3333<#: ",
|
||||
" <<< ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,457 @@
|
|||
/************************************/
|
||||
/* ArcBall.c (c) Ken Shoemake, 1993 */
|
||||
/* Modified by Tom Bech, 1996 */
|
||||
/************************************/
|
||||
|
||||
#include <math.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <libgimp/gimp.h>
|
||||
#include "arcball.h"
|
||||
|
||||
/* Gloval variables */
|
||||
/* ================ */
|
||||
|
||||
HVect center;
|
||||
double radius;
|
||||
Quat qNow, qDown, qDrag;
|
||||
HVect vNow, vDown, vFrom, vTo, vrFrom, vrTo;
|
||||
HMatrix mNow, mDown;
|
||||
unsigned int showResult, dragging;
|
||||
ConstraintSet sets[NSets];
|
||||
int setSizes[NSets];
|
||||
AxisSet axisSet;
|
||||
int axisIndex;
|
||||
|
||||
HMatrix mId = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
|
||||
double otherAxis[][4] = {{-0.48, 0.80, 0.36, 1}};
|
||||
Quat qOne = {0, 0, 0, 1};
|
||||
|
||||
/* Externally visible methods */
|
||||
/* ========================== */
|
||||
|
||||
void ArcBall_Init();
|
||||
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);
|
||||
|
||||
/* Internal methods */
|
||||
/* ================ */
|
||||
|
||||
HMatrix *Qt_ToMatrix(Quat q,HMatrix out);
|
||||
Quat Qt_Conj(Quat q);
|
||||
Quat Qt_Mul(Quat qL, Quat qR);
|
||||
Quat Qt_FromBallPoints(HVect from, HVect to);
|
||||
void Qt_ToBallPoints(Quat q, HVect *arcFrom, HVect *arcTo);
|
||||
|
||||
HVect V3_(double x, double y, double z);
|
||||
double V3_Norm(HVect v);
|
||||
HVect V3_Unit(HVect v);
|
||||
HVect V3_Scale(HVect v, double s);
|
||||
HVect V3_Negate(HVect v);
|
||||
HVect V3_Add(HVect v1, HVect v2);
|
||||
HVect V3_Sub(HVect v1, HVect v2);
|
||||
double V3_Dot(HVect v1, HVect v2);
|
||||
HVect V3_Cross(HVect v1, HVect v2);
|
||||
HVect V3_Bisect(HVect v0, HVect v1);
|
||||
|
||||
HVect MouseOnSphere(HVect mouse, HVect ballCenter, double ballRadius);
|
||||
HVect ConstrainToAxis(HVect loose, HVect axis);
|
||||
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. */
|
||||
/* ============================================================= */
|
||||
|
||||
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. */
|
||||
/* ============================================================== */
|
||||
|
||||
HMatrix *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 ((HMatrix *)&out);
|
||||
}
|
||||
|
||||
/* Return conjugate of quaternion. */
|
||||
/* =============================== */
|
||||
|
||||
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 */
|
||||
/* ==================================== */
|
||||
|
||||
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 */
|
||||
/* ========================================================= */
|
||||
|
||||
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 */
|
||||
/* ============================================== */
|
||||
|
||||
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 */
|
||||
/* =============================== */
|
||||
|
||||
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 */
|
||||
/* ==================== */
|
||||
|
||||
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 */
|
||||
/* ======================= */
|
||||
|
||||
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 */
|
||||
/* ================================ */
|
||||
|
||||
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. */
|
||||
/* ========================================= */
|
||||
|
||||
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 */
|
||||
/* =============================== */
|
||||
|
||||
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 */
|
||||
/* ============================= */
|
||||
|
||||
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. */
|
||||
/* ================================================= */
|
||||
|
||||
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 */
|
||||
/* ========================================================== */
|
||||
|
||||
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 */
|
||||
/* ====================================================== */
|
||||
|
||||
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. */
|
||||
/* =============================================== */
|
||||
|
||||
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. */
|
||||
/* ========================================== */
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef ARCBALLH
|
||||
#define ARCBALLH
|
||||
|
||||
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;
|
||||
|
||||
extern void ArcBall_Init();
|
||||
extern void ArcBall_Place(HVect Center, double Radius);
|
||||
extern void ArcBall_UseSet(AxisSet axis_Set);
|
||||
extern void ArcBall_Update(void);
|
||||
extern void ArcBall_Value(HMatrix m_Now);
|
||||
extern void ArcBall_Values(double *alpha,double *beta,double *gamma);
|
||||
extern void ArcBall_BeginDrag(void);
|
||||
extern void ArcBall_EndDrag(void);
|
||||
extern void ArcBall_Mouse(HVect v_Now);
|
||||
extern void ArcBall_CopyMat(HMatrix inm,HMatrix outm);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
/* XPM */
|
||||
char * diffint1_xpm[] = {
|
||||
"32 32 9 1",
|
||||
" c None",
|
||||
". c #514455555144",
|
||||
"X c #514451445144",
|
||||
"o c #49244D344924",
|
||||
"O c #596559655965",
|
||||
"+ c #492449244924",
|
||||
"@ c #410345144103",
|
||||
"# c #59655D755965",
|
||||
"$ c #618561856185",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ..X ",
|
||||
" o.OO...X+ ",
|
||||
" XOOOOOO..X+ ",
|
||||
" XOOOOOOO...X+ ",
|
||||
" oOOOOOOOOO..Xo@ ",
|
||||
" .OOO###OO...XX+ ",
|
||||
" OOOO#$#OO...XXo ",
|
||||
" .OOOO###OO...XXoo ",
|
||||
" ..OOOOOOO...XXooo ",
|
||||
" X.OOOOOO....XXooo ",
|
||||
" ...O......XXooo ",
|
||||
" X........XXXoo+ ",
|
||||
" +X.....XXXXooo@ ",
|
||||
" +XXXXXXXoooo@ ",
|
||||
" +oXXXooooo@ ",
|
||||
" @+ooooo+@ ",
|
||||
" ooo ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,80 @@
|
|||
/* XPM */
|
||||
char * diffint2_xpm[] = {
|
||||
"32 32 45 1",
|
||||
" c None",
|
||||
". c #A699A699A699",
|
||||
"X c #A699A289A699",
|
||||
"o c #965896589658",
|
||||
"O c #BEFBBEFBBEFB",
|
||||
"+ c #CF3CCB2BCF3C",
|
||||
"@ c #C71BC71BC71B",
|
||||
"# c #C71BC30BC71B",
|
||||
"$ c #B6DAB6DAB6DA",
|
||||
"% c #8E388E388E38",
|
||||
"& c #69A669A669A6",
|
||||
"* c #D75CD75CD75C",
|
||||
"= c #DF7DDB6CDF7D",
|
||||
"- c #CF3CCF3CCF3C",
|
||||
"; c #965892489658",
|
||||
": c #DF7DDF7DDF7D",
|
||||
"> c #E79DE38DE79D",
|
||||
", c #D75CD34CD75C",
|
||||
"< c #AEBAAEBAAEBA",
|
||||
"1 c #9E799E799E79",
|
||||
"2 c #861786178617",
|
||||
"3 c #596559655965",
|
||||
"4 c #E79DE79DE79D",
|
||||
"5 c #B6DAB2CAB6DA",
|
||||
"6 c #71C671C671C6",
|
||||
"7 c #492449244924",
|
||||
"8 c #F7DEF3CEF7DE",
|
||||
"9 c #F7DEF7DEF7DE",
|
||||
"0 c #71C675D671C6",
|
||||
"q c #514455555144",
|
||||
"w c #FFFFFFFFFFFF",
|
||||
"e c #FFFFFBEEFFFF",
|
||||
"r c #BEFBBAEABEFB",
|
||||
"t c #EFBEEBADEFBE",
|
||||
"y c #AEBAAAAAAEBA",
|
||||
"u c #9E799A699E79",
|
||||
"i c #8E388A288E38",
|
||||
"p c #49244D344924",
|
||||
"a c #861782078617",
|
||||
"s c #69A66DB669A6",
|
||||
"d c #79E779E779E7",
|
||||
"f c #618565956185",
|
||||
"g c #514451445144",
|
||||
"h c #618561856185",
|
||||
"j c #410345144103",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .Xo ",
|
||||
" .O+@#$.%& ",
|
||||
" $*==*-#$.;& ",
|
||||
" $=:>:=,+O<123 ",
|
||||
" .*:444:*+O5X%67 ",
|
||||
" O=>4898*+O5X%0q ",
|
||||
" +=:49we=@r<1%03 ",
|
||||
" .@*=:8et-#$yui03p ",
|
||||
" X#-,**=-#r<Xoasqp ",
|
||||
" o$#+++@#r5.uidfgp ",
|
||||
" .$OOOr$<.1%as3p ",
|
||||
" %.<55<yXu%a0hg7 ",
|
||||
" &;1XX1uoia0fgpj ",
|
||||
" &2%%%iadshgpj ",
|
||||
" 36000sf3gpj ",
|
||||
" 7q33qgp7j ",
|
||||
" ppp ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,46 @@
|
|||
/* XPM */
|
||||
char * diffref1_xpm[] = {
|
||||
"32 32 11 1",
|
||||
" c None",
|
||||
". c #49244D344924",
|
||||
"X c #410345144103",
|
||||
"o c #492449244924",
|
||||
"O c #514451445144",
|
||||
"+ c #596559655965",
|
||||
"@ c #79E779E779E7",
|
||||
"# c #69A669A669A6",
|
||||
"$ c #BEFBBAEABEFB",
|
||||
"% c #8E388A288E38",
|
||||
"& c #514455555144",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ... ",
|
||||
" Xo.....oX ",
|
||||
" X.........X ",
|
||||
" X...........X ",
|
||||
" X....OO.......X ",
|
||||
" o...+@#O......o ",
|
||||
" ...O@$%&....... ",
|
||||
" ....O#%#O........ ",
|
||||
" .....O&O......... ",
|
||||
" ................. ",
|
||||
" ............... ",
|
||||
" o.............o ",
|
||||
" X.............X ",
|
||||
" X...........X ",
|
||||
" X.........X ",
|
||||
" Xo.....oX ",
|
||||
" ... ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,75 @@
|
|||
/* XPM */
|
||||
char * diffref2_xpm[] = {
|
||||
"32 32 40 1",
|
||||
" c None",
|
||||
". c #D75CD34CD75C",
|
||||
"X c #CF3CCF3CCF3C",
|
||||
"o c #BEFBBAEABEFB",
|
||||
"O c #F7DEF3CEF7DE",
|
||||
"+ c #F7DEF7DEF7DE",
|
||||
"@ c #FFFFFBEEFFFF",
|
||||
"# c #EFBEEBADEFBE",
|
||||
"$ c #D75CD75CD75C",
|
||||
"% c #B6DAB2CAB6DA",
|
||||
"& c #79E779E779E7",
|
||||
"* c #E79DE79DE79D",
|
||||
"= c #FFFFFFFFFFFF",
|
||||
"- c #EFBEEFBEEFBE",
|
||||
"; c #E79DE38DE79D",
|
||||
": c #C71BC71BC71B",
|
||||
"> c #A699A289A699",
|
||||
", c #618565956185",
|
||||
"< c #AEBAAEBAAEBA",
|
||||
"1 c #861786178617",
|
||||
"2 c #492449244924",
|
||||
"3 c #8E388E388E38",
|
||||
"4 c #596559655965",
|
||||
"5 c #CF3CCB2BCF3C",
|
||||
"6 c #618561856185",
|
||||
"7 c #DF7DDB6CDF7D",
|
||||
"8 c #C71BC30BC71B",
|
||||
"9 c #AEBAAAAAAEBA",
|
||||
"0 c #8E388A288E38",
|
||||
"q c #49244D344924",
|
||||
"w c #9E799E799E79",
|
||||
"e c #79E77DF779E7",
|
||||
"r c #965892489658",
|
||||
"t c #71C671C671C6",
|
||||
"y c #514451445144",
|
||||
"u c #9E799A699E79",
|
||||
"i c #861782078617",
|
||||
"p c #69A66DB669A6",
|
||||
"a c #514455555144",
|
||||
"s c #410345144103",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .Xo ",
|
||||
" .O+@@#$%& ",
|
||||
" *=====@-$%& ",
|
||||
" *=======+;:>, ",
|
||||
" .========+*X<12 ",
|
||||
" O========+*X%34 ",
|
||||
" +========O;5<36 ",
|
||||
" .@=======@#78906q ",
|
||||
" X@======@O;Xowe4q ",
|
||||
" o#@====@O*$89rtyq ",
|
||||
" $-+++O#;$:%ui6q ",
|
||||
" %$;**;7X8%w0py2 ",
|
||||
" &%:XX58o9u0taqs ",
|
||||
" &><%<9wripaqs ",
|
||||
" ,1330et6yqs ",
|
||||
" 24664yq2s ",
|
||||
" qqq ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,75 @@
|
|||
/* XPM */
|
||||
char * high1_xpm[] = {
|
||||
"32 32 40 1",
|
||||
" c None",
|
||||
". c #D75CD34CD75C",
|
||||
"X c #CF3CCF3CCF3C",
|
||||
"o c #BEFBBAEABEFB",
|
||||
"O c #F7DEF3CEF7DE",
|
||||
"+ c #F7DEF7DEF7DE",
|
||||
"@ c #FFFFFBEEFFFF",
|
||||
"# c #EFBEEBADEFBE",
|
||||
"$ c #D75CD75CD75C",
|
||||
"% c #B6DAB2CAB6DA",
|
||||
"& c #79E779E779E7",
|
||||
"* c #E79DE79DE79D",
|
||||
"= c #FFFFFFFFFFFF",
|
||||
"- c #EFBEEFBEEFBE",
|
||||
"; c #E79DE38DE79D",
|
||||
": c #C71BC71BC71B",
|
||||
"> c #A699A289A699",
|
||||
", c #618565956185",
|
||||
"< c #AEBAAEBAAEBA",
|
||||
"1 c #861786178617",
|
||||
"2 c #492449244924",
|
||||
"3 c #8E388E388E38",
|
||||
"4 c #596559655965",
|
||||
"5 c #CF3CCB2BCF3C",
|
||||
"6 c #618561856185",
|
||||
"7 c #DF7DDB6CDF7D",
|
||||
"8 c #C71BC30BC71B",
|
||||
"9 c #AEBAAAAAAEBA",
|
||||
"0 c #8E388A288E38",
|
||||
"q c #49244D344924",
|
||||
"w c #9E799E799E79",
|
||||
"e c #79E77DF779E7",
|
||||
"r c #965892489658",
|
||||
"t c #71C671C671C6",
|
||||
"y c #514451445144",
|
||||
"u c #9E799A699E79",
|
||||
"i c #861782078617",
|
||||
"p c #69A66DB669A6",
|
||||
"a c #514455555144",
|
||||
"s c #410345144103",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .Xo ",
|
||||
" .O+@@#$%& ",
|
||||
" *=====@-$%& ",
|
||||
" *=======+;:>, ",
|
||||
" .========+*X<12 ",
|
||||
" O========+*X%34 ",
|
||||
" +========O;5<36 ",
|
||||
" .@=======@#78906q ",
|
||||
" X@======@O;Xowe4q ",
|
||||
" o#@====@O*$89rtyq ",
|
||||
" $-+++O#;$:%ui6q ",
|
||||
" %$;**;7X8%w0py2 ",
|
||||
" &%:XX58o9u0taqs ",
|
||||
" &><%<9wripaqs ",
|
||||
" ,1330et6yqs ",
|
||||
" 24664yq2s ",
|
||||
" qqq ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,78 @@
|
|||
/* XPM */
|
||||
char * high2_xpm[] = {
|
||||
"32 32 43 1",
|
||||
" c None",
|
||||
". c #A699A699A699",
|
||||
"X c #A699A289A699",
|
||||
"o c #965896589658",
|
||||
"O c #BEFBBEFBBEFB",
|
||||
"+ c #CF3CCB2BCF3C",
|
||||
"@ c #C71BC71BC71B",
|
||||
"# c #C71BC30BC71B",
|
||||
"$ c #B6DAB6DAB6DA",
|
||||
"% c #8E388E388E38",
|
||||
"& c #69A669A669A6",
|
||||
"* c #D75CD75CD75C",
|
||||
"= c #DF7DDB6CDF7D",
|
||||
"- c #CF3CCF3CCF3C",
|
||||
"; c #965892489658",
|
||||
": c #DF7DDF7DDF7D",
|
||||
"> c #E79DE38DE79D",
|
||||
", c #D75CD34CD75C",
|
||||
"< c #AEBAAEBAAEBA",
|
||||
"1 c #9E799E799E79",
|
||||
"2 c #861786178617",
|
||||
"3 c #596559655965",
|
||||
"4 c #E79DE79DE79D",
|
||||
"5 c #B6DAB2CAB6DA",
|
||||
"6 c #71C671C671C6",
|
||||
"7 c #492449244924",
|
||||
"8 c #F7DEF7DEF7DE",
|
||||
"9 c #71C675D671C6",
|
||||
"0 c #514455555144",
|
||||
"q c #FFFFFFFFFFFF",
|
||||
"w c #BEFBBAEABEFB",
|
||||
"e c #F7DEF3CEF7DE",
|
||||
"r c #AEBAAAAAAEBA",
|
||||
"t c #9E799A699E79",
|
||||
"y c #8E388A288E38",
|
||||
"u c #49244D344924",
|
||||
"i c #861782078617",
|
||||
"p c #69A66DB669A6",
|
||||
"a c #79E779E779E7",
|
||||
"s c #618565956185",
|
||||
"d c #514451445144",
|
||||
"f c #618561856185",
|
||||
"g c #410345144103",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .Xo ",
|
||||
" .O+@#$.%& ",
|
||||
" $*==*-#$.;& ",
|
||||
" $=:>:=,+O<123 ",
|
||||
" .*:>4>=*+O5X%67 ",
|
||||
" O=>4>8:,+O5X%90 ",
|
||||
" +=:>8qq-@w<1%93 ",
|
||||
" .@*==:e=+#$rty93u ",
|
||||
" X#-,*,*-#w<Xoip0u ",
|
||||
" o$#+++@#w5.tyasdu ",
|
||||
" .$OOOw$<.1%ip3u ",
|
||||
" %.<55<rXt%i9fd7 ",
|
||||
" &;1XX1toyi9sdug ",
|
||||
" &2%%%yiapfdug ",
|
||||
" 36999ps3dug ",
|
||||
" 70330du7g ",
|
||||
" uuu ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,179 @@
|
|||
/******************************************************/
|
||||
/* Apply mapping and shading on the whole input image */
|
||||
/******************************************************/
|
||||
|
||||
#include "mapobject_shade.h"
|
||||
|
||||
/*************/
|
||||
/* Main loop */
|
||||
/*************/
|
||||
|
||||
gdouble imat[4][4];
|
||||
|
||||
void init_compute(void)
|
||||
{
|
||||
|
||||
switch (mapvals.maptype)
|
||||
{
|
||||
case MAP_SPHERE:
|
||||
|
||||
/* Rotate the equator/northpole axis */
|
||||
/* ================================= */
|
||||
|
||||
gck_vector3_set(&mapvals.firstaxis,0.0,0.0,-1.0);
|
||||
gck_vector3_set(&mapvals.secondaxis,0.0,1.0,0.0);
|
||||
|
||||
gck_vector3_rotate(&mapvals.firstaxis,gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
gck_vector3_rotate(&mapvals.secondaxis,gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_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 */
|
||||
/* ===================== */
|
||||
|
||||
gck_vector3_set(&mapvals.firstaxis, 1.0,0.0,0.0);
|
||||
gck_vector3_set(&mapvals.secondaxis,0.0,1.0,0.0);
|
||||
gck_vector3_set(&mapvals.normal,0.0,0.0,1.0);
|
||||
|
||||
gck_vector3_rotate(&mapvals.firstaxis,gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
gck_vector3_rotate(&mapvals.secondaxis,gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
|
||||
mapvals.normal=gck_vector3_cross_product(&mapvals.firstaxis,&mapvals.secondaxis);
|
||||
|
||||
if (mapvals.normal.z<0.0)
|
||||
gck_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;
|
||||
}
|
||||
|
||||
max_depth=(gint)mapvals.maxdepth;
|
||||
}
|
||||
|
||||
void render(gdouble x,gdouble y,GckRGB *col)
|
||||
{
|
||||
GckVector3 pos;
|
||||
|
||||
pos.x=x/(gdouble)width;
|
||||
pos.y=y/(gdouble)height;
|
||||
pos.z=0.0;
|
||||
|
||||
*col=get_ray_color(&pos);
|
||||
}
|
||||
|
||||
void show_progress(gint min,gint max,gint curr)
|
||||
{
|
||||
gimp_progress_update((gdouble)curr/(gdouble)max);
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* Performs map-to-sphere on the whole input image */
|
||||
/* and updates or creates a new GIMP image. */
|
||||
/**************************************************/
|
||||
|
||||
void compute_image(void)
|
||||
{
|
||||
gint xcount,ycount;
|
||||
GckRGB color;
|
||||
glong progress_counter=0;
|
||||
GckVector3 p;
|
||||
gint32 new_image_id=-1,new_layer_id=-1;
|
||||
|
||||
init_compute();
|
||||
|
||||
if (mapvals.create_new_image==TRUE || (mapvals.transparent_background==TRUE
|
||||
&& input_drawable->bpp!=4))
|
||||
{
|
||||
/* Create a new image */
|
||||
/* ================== */
|
||||
|
||||
new_image_id=gimp_image_new(width,height,RGB);
|
||||
|
||||
if (mapvals.transparent_background==TRUE)
|
||||
{
|
||||
/* Add a layer with an alpha channel */
|
||||
/* ================================= */
|
||||
|
||||
new_layer_id=gimp_layer_new(new_image_id,"Background",width,height,RGBA_IMAGE,100.0,NORMAL_MODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a "normal" layer */
|
||||
/* ======================= */
|
||||
|
||||
new_layer_id=gimp_layer_new(new_image_id,"Background",width,height,RGB_IMAGE,100.0,NORMAL_MODE);
|
||||
}
|
||||
|
||||
gimp_image_add_layer(new_image_id,new_layer_id,0);
|
||||
output_drawable=gimp_drawable_get(new_layer_id);
|
||||
}
|
||||
|
||||
gimp_pixel_rgn_init (&dest_region, output_drawable, 0, 0, width, height, TRUE, TRUE);
|
||||
|
||||
if (mapvals.maptype==MAP_PLANE)
|
||||
gimp_progress_init("Map to object (plane)");
|
||||
else
|
||||
gimp_progress_init("Map to object (sphere)");
|
||||
|
||||
if (mapvals.antialiasing==FALSE)
|
||||
{
|
||||
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);
|
||||
if ((progress_counter++ % width)==0)
|
||||
gimp_progress_update((gdouble)progress_counter/(gdouble)maxcounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
gck_adaptive_supersample_area(0,0,width-1,height-1,max_depth,mapvals.pixeltreshold,
|
||||
render,poke,show_progress);
|
||||
|
||||
/* Update the region */
|
||||
/* ================= */
|
||||
|
||||
gimp_drawable_flush (output_drawable);
|
||||
gimp_drawable_merge_shadow (output_drawable->id, TRUE);
|
||||
gimp_drawable_update (output_drawable->id, 0, 0, width,height);
|
||||
|
||||
if (new_image_id!=-1)
|
||||
{
|
||||
gimp_display_new(new_image_id);
|
||||
gimp_displays_flush();
|
||||
gimp_drawable_detach (output_drawable);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef MAPOBJECTAPPLYH
|
||||
#define MAPOBJECTAPPLYH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gck/gck.h>
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "mapobject_main.h"
|
||||
#include "mapobject_image.h"
|
||||
|
||||
|
||||
extern gdouble imat[4][4];
|
||||
extern void init_compute(void);
|
||||
extern void compute_image(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,202 @@
|
|||
/*********************************************************/
|
||||
/* 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 "mapobject_image.h"
|
||||
|
||||
GDrawable *input_drawable,*output_drawable;
|
||||
GPixelRgn source_region,dest_region;
|
||||
|
||||
guchar *preview_rgb_data = NULL;
|
||||
GdkImage *image = NULL;
|
||||
|
||||
glong maxcounter,old_depth,max_depth;
|
||||
gint imgtype,width,height,in_channels,out_channels;
|
||||
GckRGB background;
|
||||
gdouble oldtreshold;
|
||||
|
||||
gint border_x1,border_y1,border_x2,border_y2;
|
||||
|
||||
/******************/
|
||||
/* Implementation */
|
||||
/******************/
|
||||
|
||||
GckRGB peek(gint x,gint y)
|
||||
{
|
||||
static guchar data[4];
|
||||
GckRGB color;
|
||||
|
||||
gimp_pixel_rgn_get_pixel(&source_region,data,x,y);
|
||||
|
||||
color.r=(gdouble)(data[0])/255.0;
|
||||
color.g=(gdouble)(data[1])/255.0;
|
||||
color.b=(gdouble)(data[2])/255.0;
|
||||
|
||||
if (input_drawable->bpp==4)
|
||||
{
|
||||
if (in_channels==4)
|
||||
color.a=(gdouble)(data[3])/255.0;
|
||||
else
|
||||
color.a=1.0;
|
||||
}
|
||||
else
|
||||
color.a=1.0;
|
||||
|
||||
return(color);
|
||||
}
|
||||
|
||||
void poke(gint x,gint y,GckRGB *color)
|
||||
{
|
||||
static guchar data[4];
|
||||
|
||||
data[0]=(guchar)(color->r*255.0);
|
||||
data[1]=(guchar)(color->g*255.0);
|
||||
data[2]=(guchar)(color->b*255.0);
|
||||
data[3]=(guchar)(color->a*255.0);
|
||||
|
||||
gimp_pixel_rgn_set_pixel(&dest_region,data,x,y);
|
||||
}
|
||||
|
||||
gint checkbounds(gint x,gint y)
|
||||
{
|
||||
if (x<border_x1 || y<border_y1 || x>=border_x2 || y>=border_y2)
|
||||
return(FALSE);
|
||||
else
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
GckVector3 int_to_pos(gint x,gint y)
|
||||
{
|
||||
GckVector3 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. */
|
||||
/**********************************************/
|
||||
|
||||
GckRGB get_image_color(gdouble u,gdouble v,gint *inside)
|
||||
{
|
||||
gint x1, y1, x2, y2;
|
||||
GckRGB 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(gck_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(gck_bilinear_rgba(u * width, v * height, p));
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Allocate memory for temporary images */
|
||||
/****************************************/
|
||||
|
||||
gint image_setup(GDrawable *drawable,gint interactive)
|
||||
{
|
||||
glong numbytes;
|
||||
|
||||
/* Set the tile cache size */
|
||||
/* ======================= */
|
||||
|
||||
gimp_tile_cache_ntiles((drawable->width + gimp_tile_width() - 1) /
|
||||
gimp_tile_width());
|
||||
|
||||
/* Get some useful info on the input drawable */
|
||||
/* ========================================== */
|
||||
|
||||
input_drawable=drawable;
|
||||
output_drawable=drawable;
|
||||
|
||||
gimp_drawable_mask_bounds (drawable->id, &border_x1, &border_y1, &border_x2, &border_y2);
|
||||
|
||||
width=input_drawable->width;
|
||||
height=input_drawable->height;
|
||||
|
||||
gimp_pixel_rgn_init (&source_region, input_drawable, 0, 0, width, height, FALSE, FALSE);
|
||||
|
||||
maxcounter=(glong)width*(glong)height;
|
||||
|
||||
/* Assume at least RGB */
|
||||
/* =================== */
|
||||
|
||||
in_channels=3;
|
||||
if (gimp_drawable_has_alpha(input_drawable->id)==TRUE)
|
||||
in_channels++;
|
||||
|
||||
if (interactive==TRUE)
|
||||
{
|
||||
/* Allocate memory for temp. images */
|
||||
/* ================================ */
|
||||
|
||||
numbytes=PREVIEW_HEIGHT*PREVIEW_WIDTH*3;
|
||||
|
||||
image=gdk_image_new(GDK_IMAGE_FASTEST,appwin->visinfo->visual,PREVIEW_WIDTH,PREVIEW_HEIGHT);
|
||||
if (image==NULL)
|
||||
return(FALSE);
|
||||
|
||||
preview_rgb_data=(guchar *)malloc((size_t)numbytes);
|
||||
if (preview_rgb_data==NULL)
|
||||
return(FALSE);
|
||||
memset(preview_rgb_data,0,numbytes);
|
||||
|
||||
/* Convert from raw RGB to GdkImage */
|
||||
/* ================================ */
|
||||
|
||||
gck_rgb_to_gdkimage(appwin->visinfo,preview_rgb_data,image,PREVIEW_WIDTH,PREVIEW_HEIGHT);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef MAPOBJECTIMAGEH
|
||||
#define MAPOBJECTIMAGEH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gck/gck.h>
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "mapobject_main.h"
|
||||
#include "mapobject_preview.h"
|
||||
#include "mapobject_shade.h"
|
||||
#include "mapobject_ui.h"
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern GDrawable *input_drawable,*output_drawable;
|
||||
extern GPixelRgn source_region,dest_region;
|
||||
|
||||
extern guchar *preview_rgb_data;
|
||||
extern GdkImage *image;
|
||||
|
||||
extern glong maxcounter,old_depth,max_depth;
|
||||
extern gint imgtype,width,height,in_channels,out_channels;
|
||||
extern GckRGB background;
|
||||
extern gdouble oldtreshold;
|
||||
|
||||
extern gint border_x1,border_y1,border_x2,border_y2;
|
||||
|
||||
extern GTile *current_in_tile, *current_out_tile;
|
||||
|
||||
/* Externally visible functions */
|
||||
/* ============================ */
|
||||
|
||||
extern gint image_setup (GDrawable *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 GckRGB peek (gint x,gint y);
|
||||
extern void poke (gint x,gint y,GckRGB *color);
|
||||
extern GckVector3 int_to_pos (gint x,gint y);
|
||||
extern void pos_to_int (gdouble x,gdouble y,gint *scr_x,gint *scr_y);
|
||||
extern GckRGB get_image_color (gdouble u,gdouble v,gint *inside);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,284 @@
|
|||
/*********************************************************************************/
|
||||
/* MapObject 1.00 -- image filter plug-in for The Gimp program */
|
||||
/* Copyright (C) 1996-98 Tom Bech */
|
||||
/* Copyright (C) 1996-98 Federico Mena Quintero */
|
||||
/*===============================================================================*/
|
||||
/* E-mail: tomb@gimp.org (Tom) or quartic@gimp.org (Federico) */
|
||||
/* You can contact the original The Gimp authors at gimp@xcf.berkeley.edu */
|
||||
/*===============================================================================*/
|
||||
/* 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 2 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 (read the "COPYING" file); if not, write to the Free Software */
|
||||
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/*===============================================================================*/
|
||||
/* In other words, you can't sue us for whatever happens while using this ;) */
|
||||
/*********************************************************************************/
|
||||
|
||||
#include "mapobject_main.h"
|
||||
|
||||
/* Global variables */
|
||||
/* ================ */
|
||||
|
||||
MapObjectValues mapvals;
|
||||
|
||||
/******************/
|
||||
/* Implementation */
|
||||
/******************/
|
||||
|
||||
void mapobject_interactive (GDrawable *drawable);
|
||||
void mapobject_noninteractive (GDrawable *drawable);
|
||||
|
||||
/*************************************/
|
||||
/* Set parameters to standard values */
|
||||
/*************************************/
|
||||
|
||||
void set_default_settings(void)
|
||||
{
|
||||
gck_vector3_set(&mapvals.viewpoint, 0.5,0.5,2.0);
|
||||
gck_vector3_set(&mapvals.firstaxis, 1.0,0.0,0.0);
|
||||
gck_vector3_set(&mapvals.secondaxis, 0.0,1.0,0.0);
|
||||
gck_vector3_set(&mapvals.normal, 0.0,0.0,1.0);
|
||||
gck_vector3_set(&mapvals.position, 0.5,0.5,0.0);
|
||||
gck_vector3_set(&mapvals.lightsource.position, -0.5,-0.5,2.0);
|
||||
gck_vector3_set(&mapvals.lightsource.direction, -1.0,-1.0,1.0);
|
||||
|
||||
mapvals.maptype=MAP_PLANE;
|
||||
|
||||
mapvals.pixeltreshold=0.25;
|
||||
mapvals.alpha=mapvals.beta=mapvals.gamma=0.0;
|
||||
mapvals.maxdepth=3.0;
|
||||
mapvals.radius=0.25;
|
||||
|
||||
mapvals.preview_zoom_factor=0;
|
||||
|
||||
mapvals.lightsource.type=POINT_LIGHT;
|
||||
|
||||
mapvals.antialiasing=TRUE;
|
||||
mapvals.create_new_image=FALSE;
|
||||
mapvals.transparent_background=FALSE;
|
||||
mapvals.tiled=FALSE;
|
||||
mapvals.showgrid=FALSE;
|
||||
mapvals.tooltips_enabled=TRUE;
|
||||
|
||||
mapvals.lightsource.intensity = 1.0;
|
||||
gck_rgb_set(&mapvals.lightsource.color,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;
|
||||
}
|
||||
|
||||
MAIN();
|
||||
|
||||
static void query(void)
|
||||
{
|
||||
|
||||
static GParamDef args[] =
|
||||
{
|
||||
{ PARAM_INT32, "run_mode", "Interactive (0), non-interactive (1)" },
|
||||
{ PARAM_IMAGE, "image", "Input image" },
|
||||
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
|
||||
{ PARAM_INT32, "maptype", "Type of mapping (0=plane,1=sphere)" },
|
||||
{ PARAM_FLOAT, "viewpoint_x", "Position of viewpoint (x,y,z)" },
|
||||
{ PARAM_FLOAT, "viewpoint_y", "Position of viewpoint (x,y,z)" },
|
||||
{ PARAM_FLOAT, "viewpoint_z", "Position of viewpoint (x,y,z)" },
|
||||
{ PARAM_FLOAT, "position_x", "Object position (x,y,z)" },
|
||||
{ PARAM_FLOAT, "position_y", "Object position (x,y,z)" },
|
||||
{ PARAM_FLOAT, "position_z", "Object position (x,y,z)" },
|
||||
{ PARAM_FLOAT, "firstaxis_x", "First axis of object [x,y,z]" },
|
||||
{ PARAM_FLOAT, "firstaxis_y", "First axis of object [x,y,z]" },
|
||||
{ PARAM_FLOAT, "firstaxis_z", "First axis of object [x,y,z]" },
|
||||
{ PARAM_FLOAT, "secondaxis_x", "Second axis of object [x,y,z]" },
|
||||
{ PARAM_FLOAT, "secondaxis_y", "Second axis of object [x,y,z]" },
|
||||
{ PARAM_FLOAT, "secondaxis_z", "Second axis of object [x,y,z]" },
|
||||
{ PARAM_FLOAT, "rotationangle_x", "Axis rotation (xy,xz,yz) in degrees" },
|
||||
{ PARAM_FLOAT, "rotationangle_y", "Axis rotation (xy,xz,yz) in degrees" },
|
||||
{ PARAM_FLOAT, "rotationangle_z", "Axis rotation (xy,xz,yz) in degrees" },
|
||||
{ PARAM_INT32, "lighttype", "Type of lightsource (0=point,1=directional,3=none)" },
|
||||
{ PARAM_COLOR, "lightcolor", "Lightsource color (r,g,b)" },
|
||||
{ PARAM_FLOAT, "lightposition_x", "Lightsource position (x,y,z)" },
|
||||
{ PARAM_FLOAT, "lightposition_y", "Lightsource position (x,y,z)" },
|
||||
{ PARAM_FLOAT, "lightposition_z", "Lightsource position (x,y,z)" },
|
||||
{ PARAM_FLOAT, "lightdirection_x", "Lightsource direction [x,y,z]" },
|
||||
{ PARAM_FLOAT, "lightdirection_y", "Lightsource direction [x,y,z]" },
|
||||
{ PARAM_FLOAT, "lightdirection_z", "Lightsource direction [x,y,z]" },
|
||||
{ PARAM_FLOAT, "ambient_intensity", "Material ambient intensity (0..1)" },
|
||||
{ PARAM_FLOAT, "diffuse_intensity", "Material diffuse intensity (0..1)" },
|
||||
{ PARAM_FLOAT, "diffuse_reflectivity", "Material diffuse reflectivity (0..1)" },
|
||||
{ PARAM_FLOAT, "specular_reflectivity", "Material specular reflectivity (0..1)" },
|
||||
{ PARAM_FLOAT, "highlight", "Material highlight (0..->), note: it's expotential" },
|
||||
{ PARAM_INT32, "antialiasing", "Apply antialiasing (TRUE/FALSE)" },
|
||||
{ PARAM_INT32, "tiled", "Tile source image (TRUE/FALSE)" },
|
||||
{ PARAM_INT32, "newimage", "Create a new image (TRUE/FALSE)" },
|
||||
{ PARAM_INT32, "transparentbackground", "Make background transparent (TRUE/FALSE)" },
|
||||
{ PARAM_FLOAT, "radius", "Sphere radius (only used when maptype=1)" }
|
||||
};
|
||||
|
||||
static GParamDef *return_vals = NULL;
|
||||
static gint nargs = sizeof (args) / sizeof (args[0]);
|
||||
static gint nreturn_vals = 0;
|
||||
|
||||
gimp_install_procedure ("plug_in_map_object",
|
||||
"Maps a picture to a object (plane, sphere)",
|
||||
"No help yet",
|
||||
"Tom Bech & Federico Mena Quintero",
|
||||
"Tom Bech & Federico Mena Quintero",
|
||||
"Version 1.00, March 15 1998",
|
||||
"<Image>/Filters/Map/Map Object",
|
||||
"RGB*",
|
||||
PROC_PLUG_IN,
|
||||
nargs, nreturn_vals,
|
||||
args, return_vals);
|
||||
}
|
||||
|
||||
static void run(gchar *name,
|
||||
gint nparams,
|
||||
GParam *param,
|
||||
gint *nreturn_vals,
|
||||
GParam **return_vals)
|
||||
{
|
||||
static GParam values[1];
|
||||
GDrawable *drawable;
|
||||
GRunModeType run_mode;
|
||||
GStatusType status = STATUS_SUCCESS;
|
||||
|
||||
run_mode = param[0].data.d_int32;
|
||||
|
||||
values[0].type = PARAM_STATUS;
|
||||
values[0].data.d_status = status;
|
||||
|
||||
*nreturn_vals = 1;
|
||||
*return_vals = values;
|
||||
|
||||
/* Set default values */
|
||||
/* ================== */
|
||||
|
||||
set_default_settings();
|
||||
|
||||
/* Get the specified drawable */
|
||||
/* ========================== */
|
||||
|
||||
drawable = gimp_drawable_get (param[2].data.d_drawable);
|
||||
|
||||
switch (run_mode)
|
||||
{
|
||||
case RUN_INTERACTIVE:
|
||||
|
||||
/* Possibly retrieve data */
|
||||
/* ====================== */
|
||||
|
||||
gimp_get_data ("plug_in_map_object", &mapvals);
|
||||
mapobject_interactive(drawable);
|
||||
gimp_set_data("plug_in_map_object", &mapvals, sizeof(MapObjectValues));
|
||||
break;
|
||||
case RUN_WITH_LAST_VALS:
|
||||
gimp_get_data ("plug_in_map_object", &mapvals);
|
||||
image_setup(drawable,FALSE);
|
||||
compute_image();
|
||||
break;
|
||||
case RUN_NONINTERACTIVE:
|
||||
if (nparams != 37)
|
||||
status = STATUS_CALLING_ERROR;
|
||||
else if (status == STATUS_SUCCESS)
|
||||
{
|
||||
mapvals.maptype = (MapType)param[3].data.d_int32;
|
||||
mapvals.viewpoint.x = param[4].data.d_float;
|
||||
mapvals.viewpoint.y = param[5].data.d_float;
|
||||
mapvals.viewpoint.z = param[6].data.d_float;
|
||||
mapvals.position.x = param[7].data.d_float;
|
||||
mapvals.position.y = param[8].data.d_float;
|
||||
mapvals.position.z = param[9].data.d_float;
|
||||
mapvals.firstaxis.x = param[10].data.d_float;
|
||||
mapvals.firstaxis.y = param[11].data.d_float;
|
||||
mapvals.firstaxis.z = param[12].data.d_float;
|
||||
mapvals.secondaxis.x = param[13].data.d_float;
|
||||
mapvals.secondaxis.y = param[14].data.d_float;
|
||||
mapvals.secondaxis.z = param[15].data.d_float;
|
||||
mapvals.alpha = param[16].data.d_float;
|
||||
mapvals.beta = param[17].data.d_float;
|
||||
mapvals.gamma = param[18].data.d_float;
|
||||
mapvals.lightsource.type = (LightType)param[19].data.d_int32;
|
||||
mapvals.lightsource.color.r = param[20].data.d_color.red;
|
||||
mapvals.lightsource.color.g = param[20].data.d_color.green;
|
||||
mapvals.lightsource.color.b = param[20].data.d_color.blue;
|
||||
mapvals.lightsource.position.x = param[21].data.d_float;
|
||||
mapvals.lightsource.position.y = param[22].data.d_float;
|
||||
mapvals.lightsource.position.z = param[23].data.d_float;
|
||||
mapvals.lightsource.direction.x = param[24].data.d_float;
|
||||
mapvals.lightsource.direction.y = param[25].data.d_float;
|
||||
mapvals.lightsource.direction.z = param[26].data.d_float;
|
||||
mapvals.material.ambient_int = param[27].data.d_float;
|
||||
mapvals.material.diffuse_int = param[28].data.d_float;
|
||||
mapvals.material.diffuse_ref = param[29].data.d_float;
|
||||
mapvals.material.specular_ref = param[30].data.d_float;
|
||||
mapvals.material.highlight = param[31].data.d_float;
|
||||
mapvals.antialiasing = (gint)param[32].data.d_int32;
|
||||
mapvals.tiled = (gint)param[33].data.d_int32;
|
||||
mapvals.create_new_image = (gint)param[34].data.d_int32;
|
||||
mapvals.transparent_background = (gint)param[35].data.d_int32;
|
||||
mapvals.radius = param[36].data.d_float;
|
||||
|
||||
image_setup(drawable, FALSE);
|
||||
compute_image();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
values[0].data.d_status = status;
|
||||
gimp_drawable_detach(drawable);
|
||||
}
|
||||
|
||||
GPlugInInfo PLUG_IN_INFO =
|
||||
{
|
||||
NULL, /* init_proc */
|
||||
NULL, /* quit_proc */
|
||||
query, /* query_proc */
|
||||
run, /* run_proc */
|
||||
};
|
||||
|
||||
void mapobject_interactive(GDrawable *drawable)
|
||||
{
|
||||
gchar **argv;
|
||||
gint argc;
|
||||
|
||||
argc = 1;
|
||||
argv = g_new (gchar *, 1);
|
||||
argv[0] = g_strdup ("map_object");
|
||||
|
||||
gdk_set_use_xshm(gimp_use_xshm());
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
gtk_rc_parse (gimp_gtkrc ());
|
||||
|
||||
/* Set up ArcBall stuff */
|
||||
/* ==================== */
|
||||
|
||||
/*ArcBall_Init(); */
|
||||
|
||||
/* Create application window */
|
||||
/* ========================= */
|
||||
|
||||
create_main_dialog();
|
||||
|
||||
/* Prepare images */
|
||||
/* ============== */
|
||||
|
||||
image_setup(drawable,TRUE);
|
||||
|
||||
/* Gtk main event loop */
|
||||
/* =================== */
|
||||
|
||||
gtk_main();
|
||||
gdk_flush();
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef MAPOBJECTMAINH
|
||||
#define MAPOBJECTMAINH
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gck/gck.h>
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "arcball.h"
|
||||
#include "mapobject_ui.h"
|
||||
#include "mapobject_image.h"
|
||||
#include "mapobject_apply.h"
|
||||
#include "mapobject_preview.h"
|
||||
|
||||
/* Defines and stuff */
|
||||
/* ================= */
|
||||
|
||||
#define TILE_CACHE_SIZE 16
|
||||
|
||||
/* Typedefs */
|
||||
/* ======== */
|
||||
|
||||
typedef enum {
|
||||
POINT_LIGHT,
|
||||
DIRECTIONAL_LIGHT,
|
||||
NO_LIGHT
|
||||
} LightType;
|
||||
|
||||
typedef enum {
|
||||
MAP_PLANE,
|
||||
MAP_SPHERE
|
||||
} MapType;
|
||||
|
||||
/* Typedefs */
|
||||
/* ======== */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gdouble ambient_int;
|
||||
gdouble diffuse_int;
|
||||
gdouble diffuse_ref;
|
||||
gdouble specular_ref;
|
||||
gdouble highlight;
|
||||
GckRGB color;
|
||||
} MaterialSettings;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LightType type;
|
||||
GckVector3 position;
|
||||
GckVector3 direction;
|
||||
GckRGB color;
|
||||
gdouble intensity;
|
||||
} LightSettings;
|
||||
|
||||
typedef struct {
|
||||
GckVector3 viewpoint,firstaxis,secondaxis,normal,position;
|
||||
LightSettings lightsource;
|
||||
|
||||
MaterialSettings material;
|
||||
MaterialSettings refmaterial;
|
||||
|
||||
MapType maptype;
|
||||
|
||||
gint antialiasing;
|
||||
gint create_new_image;
|
||||
gint transparent_background;
|
||||
gint tiled;
|
||||
gint showgrid;
|
||||
gint tooltips_enabled;
|
||||
|
||||
glong preview_zoom_factor;
|
||||
|
||||
gdouble alpha,beta,gamma;
|
||||
gdouble maxdepth;
|
||||
gdouble pixeltreshold;
|
||||
gdouble radius;
|
||||
|
||||
} MapObjectValues;
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern MapObjectValues mapvals;
|
||||
extern GckRGB background;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef MAPOBJECTPIXMAPSH
|
||||
#define MAPOBJECTPIXMAPSH
|
||||
|
||||
#include "amb1.xpm"
|
||||
#include "amb2.xpm"
|
||||
#include "diffint1.xpm"
|
||||
#include "diffint2.xpm"
|
||||
#include "diffref1.xpm"
|
||||
#include "diffref2.xpm"
|
||||
#include "specref1.xpm"
|
||||
#include "specref2.xpm"
|
||||
#include "high1.xpm"
|
||||
#include "high2.xpm"
|
||||
|
||||
extern char *amb1_xpm[];
|
||||
extern char *amb2_xpm[];
|
||||
extern char *diffint1_xpm[];
|
||||
extern char *diffint2_xpm[];
|
||||
extern char *diffref1_xpm[];
|
||||
extern char *diffref2_xpm[];
|
||||
extern char *specref1_xpm[];
|
||||
extern char *specref2_xpm[];
|
||||
extern char *high1_xpm[];
|
||||
extern char *high2_xpm[];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,533 @@
|
|||
/*************************************************/
|
||||
/* Compute a preview image and preview wireframe */
|
||||
/*************************************************/
|
||||
|
||||
#include "mapobject_preview.h"
|
||||
|
||||
line linetab[WIRESIZE*2+8];
|
||||
gdouble mat[3][4];
|
||||
|
||||
gint lightx,lighty;
|
||||
BackBuffer backbuf={0,0,0,0,NULL};
|
||||
|
||||
/* Protos */
|
||||
/* ====== */
|
||||
|
||||
void update_light (gint xpos,gint ypos);
|
||||
void draw_light_marker (gint xpos,gint ypos);
|
||||
void clear_light_marker (void);
|
||||
void draw_wireframe_plane(gint startx,gint starty,gint pw,gint ph);
|
||||
void draw_wireframe_sphere(gint startx,gint starty,gint pw,gint ph);
|
||||
void clear_wireframe(void);
|
||||
|
||||
/**************************************************************/
|
||||
/* Computes a preview of the rectangle starting at (x,y) with */
|
||||
/* dimensions (w,h), placing the result in preview_RGB_data. */
|
||||
/**************************************************************/
|
||||
|
||||
void compute_preview(gint x,gint y,gint w,gint h,gint pw,gint ph)
|
||||
{
|
||||
gdouble xpostab[PREVIEW_WIDTH],ypostab[PREVIEW_HEIGHT],realw,realh;
|
||||
GckVector3 p1,p2;
|
||||
GckRGB color,lightcheck,darkcheck,temp;
|
||||
guchar r,g,b;
|
||||
gint xcnt,ycnt,f1,f2;
|
||||
glong index=0;
|
||||
|
||||
init_compute();
|
||||
|
||||
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*((double)xcnt/(double)pw);
|
||||
|
||||
for (ycnt=0;ycnt<ph;ycnt++)
|
||||
ypostab[ycnt]=p1.y+realh*((double)ycnt/(double)ph);
|
||||
|
||||
/* Compute preview using the offset tables */
|
||||
/* ======================================= */
|
||||
|
||||
if (mapvals.transparent_background==TRUE)
|
||||
gck_rgba_set(&background,0.0,0.0,0.0,0.0);
|
||||
else
|
||||
{
|
||||
gimp_palette_get_background(&r,&g,&b);
|
||||
background.r=(gdouble)r/255.0;
|
||||
background.g=(gdouble)g/255.0;
|
||||
background.b=(gdouble)b/255.0;
|
||||
background.a=1.0;
|
||||
}
|
||||
|
||||
gck_rgb_set(&lightcheck,0.75,0.75,0.75);
|
||||
gck_rgb_set(&darkcheck, 0.50,0.50,0.50);
|
||||
gck_vector3_set(&p2,-1.0,-1.0,0.0);
|
||||
|
||||
for (ycnt=0;ycnt<ph;ycnt++)
|
||||
{
|
||||
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
|
||||
{
|
||||
gck_rgb_mul(&color,color.a);
|
||||
temp=lightcheck;
|
||||
gck_rgb_mul(&temp,1.0-color.a);
|
||||
gck_rgb_add(&color,&temp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (color.a==0.0)
|
||||
color=darkcheck;
|
||||
else
|
||||
{
|
||||
gck_rgb_mul(&color,color.a);
|
||||
temp=darkcheck;
|
||||
gck_rgb_mul(&temp,1.0-color.a);
|
||||
gck_rgb_add(&color,&temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preview_rgb_data[index++]=(guchar)(color.r*255.0);
|
||||
preview_rgb_data[index++]=(guchar)(color.g*255.0);
|
||||
preview_rgb_data[index++]=(guchar)(color.b*255.0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert to visual type */
|
||||
/* ====================== */
|
||||
|
||||
gck_rgb_to_gdkimage(appwin->visinfo,preview_rgb_data,image,pw,ph);
|
||||
}
|
||||
|
||||
/*************************************************/
|
||||
/* 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 */
|
||||
/****************************************/
|
||||
|
||||
void draw_light_marker(gint xpos,gint ypos)
|
||||
{
|
||||
gck_gc_set_foreground(appwin->visinfo,gc,0,50,255);
|
||||
gck_gc_set_background(appwin->visinfo,gc,0,0,0);
|
||||
|
||||
gdk_gc_set_function(gc,GDK_COPY);
|
||||
|
||||
if (mapvals.lightsource.type==POINT_LIGHT)
|
||||
{
|
||||
lightx=xpos;
|
||||
lighty=ypos;
|
||||
|
||||
/* Save background */
|
||||
/* =============== */
|
||||
|
||||
backbuf.x=lightx-7;
|
||||
backbuf.y=lighty-7;
|
||||
backbuf.w=14;
|
||||
backbuf.h=14;
|
||||
|
||||
/* X doesn't like images that's outside a window, make sure */
|
||||
/* we get the backbuffer image from within the boundaries */
|
||||
/* ======================================================== */
|
||||
|
||||
if (backbuf.x<0)
|
||||
backbuf.x=0;
|
||||
else if ((backbuf.x+backbuf.w)>PREVIEW_WIDTH)
|
||||
backbuf.w=(PREVIEW_WIDTH-backbuf.x);
|
||||
if (backbuf.y<0)
|
||||
backbuf.y=0;
|
||||
else if ((backbuf.y+backbuf.h)>PREVIEW_HEIGHT)
|
||||
backbuf.h=(PREVIEW_WIDTH-backbuf.y);
|
||||
|
||||
backbuf.image=gdk_image_get(previewarea->window,backbuf.x,backbuf.y,backbuf.w,backbuf.h);
|
||||
gdk_draw_arc(previewarea->window,gc,TRUE,lightx-7,lighty-7,14,14,0,360*64);
|
||||
}
|
||||
}
|
||||
|
||||
void clear_light_marker()
|
||||
{
|
||||
/* Restore background if it has been saved */
|
||||
/* ======================================= */
|
||||
|
||||
if (backbuf.image!=NULL)
|
||||
{
|
||||
gck_gc_set_foreground(appwin->visinfo,gc,255,255,255);
|
||||
gck_gc_set_background(appwin->visinfo,gc,0,0,0);
|
||||
|
||||
gdk_gc_set_function(gc,GDK_COPY);
|
||||
gdk_draw_image(previewarea->window,gc,backbuf.image,0,0,backbuf.x,backbuf.y,
|
||||
backbuf.w,backbuf.h);
|
||||
gdk_image_destroy(backbuf.image);
|
||||
backbuf.image=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_lights(gint startx,gint starty,gint pw,gint ph)
|
||||
{
|
||||
gdouble dxpos,dypos;
|
||||
gint xpos,ypos;
|
||||
|
||||
clear_light_marker();
|
||||
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&dxpos,&dypos,&mapvals.viewpoint,
|
||||
&mapvals.lightsource.position);
|
||||
xpos=(gint)(dxpos+0.5);
|
||||
ypos=(gint)(dypos+0.5);
|
||||
|
||||
if (xpos>=0 && xpos<=PREVIEW_WIDTH && ypos>=0 && ypos<=PREVIEW_HEIGHT)
|
||||
draw_light_marker(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.preview_zoom_factor;
|
||||
ph=PREVIEW_HEIGHT >> mapvals.preview_zoom_factor;
|
||||
startx=(PREVIEW_WIDTH-pw)>>1;
|
||||
starty=(PREVIEW_HEIGHT-ph)>>1;
|
||||
|
||||
gck_2d_to_3d(startx,starty,pw,ph,xpos,ypos,&mapvals.viewpoint,&mapvals.lightsource.position);
|
||||
draw_lights(startx,starty,pw,ph);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* Draw preview image. if DoCompute is TRUE then recompute image. */
|
||||
/******************************************************************/
|
||||
|
||||
void draw_preview_image(gint docompute)
|
||||
{
|
||||
gint startx,starty,pw,ph;
|
||||
|
||||
gck_gc_set_foreground(appwin->visinfo,gc,255,255,255);
|
||||
gck_gc_set_background(appwin->visinfo,gc,0,0,0);
|
||||
|
||||
gdk_gc_set_function(gc,GDK_COPY);
|
||||
linetab[0].x1=-1;
|
||||
|
||||
pw=PREVIEW_WIDTH >> mapvals.preview_zoom_factor;
|
||||
ph=PREVIEW_HEIGHT >> mapvals.preview_zoom_factor;
|
||||
startx=(PREVIEW_WIDTH-pw)>>1;
|
||||
starty=(PREVIEW_HEIGHT-ph)>>1;
|
||||
|
||||
if (docompute==TRUE)
|
||||
{
|
||||
gck_cursor_set(previewarea->window,GDK_WATCH);
|
||||
compute_preview(0,0,width-1,height-1,pw,ph);
|
||||
gck_cursor_set(previewarea->window,GDK_HAND2);
|
||||
clear_light_marker();
|
||||
}
|
||||
|
||||
if (pw!=PREVIEW_WIDTH)
|
||||
gdk_window_clear(previewarea->window);
|
||||
|
||||
gdk_draw_image(previewarea->window,gc,image,0,0,startx,starty,pw,ph);
|
||||
draw_lights(startx,starty,pw,ph);
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Draw preview wireframe */
|
||||
/**************************/
|
||||
|
||||
void draw_preview_wireframe(void)
|
||||
{
|
||||
gint startx,starty,pw,ph;
|
||||
|
||||
gck_gc_set_foreground(appwin->visinfo,gc,255,255,255);
|
||||
gck_gc_set_background(appwin->visinfo,gc,0,0,0);
|
||||
|
||||
gdk_gc_set_function(gc,GDK_INVERT);
|
||||
|
||||
pw=PREVIEW_WIDTH >> mapvals.preview_zoom_factor;
|
||||
ph=PREVIEW_HEIGHT >> mapvals.preview_zoom_factor;
|
||||
startx=(PREVIEW_WIDTH-pw)>>1;
|
||||
starty=(PREVIEW_HEIGHT-ph)>>1;
|
||||
|
||||
clear_wireframe();
|
||||
draw_wireframe(startx,starty,pw,ph);
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* Draw a wireframe preview */
|
||||
/****************************/
|
||||
|
||||
void draw_wireframe(gint startx,gint starty,gint pw,gint ph)
|
||||
{
|
||||
switch (mapvals.maptype)
|
||||
{
|
||||
case MAP_PLANE:
|
||||
draw_wireframe_plane(startx,starty,pw,ph);
|
||||
break;
|
||||
case MAP_SPHERE:
|
||||
draw_wireframe_sphere(startx,starty,pw,ph);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_wireframe_plane(gint startx,gint starty,gint pw,gint ph)
|
||||
{
|
||||
GckVector3 v1,v2,a,b,c,d,dir1,dir2;
|
||||
gint cnt,n=0;
|
||||
gdouble x1,y1,x2,y2,cx1,cy1,cx2,cy2,fac;
|
||||
|
||||
/* Find rotated box corners */
|
||||
/* ======================== */
|
||||
|
||||
gck_vector3_set(&v1,0.5,0.0,0.0);
|
||||
gck_vector3_set(&v2,0.0,0.5,0.0);
|
||||
|
||||
gck_vector3_rotate(&v1,gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
gck_vector3_rotate(&v2,gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
|
||||
dir1=v1; gck_vector3_normalize(&dir1);
|
||||
dir2=v2; gck_vector3_normalize(&dir2);
|
||||
|
||||
fac=1.0/(gdouble)WIRESIZE;
|
||||
|
||||
gck_vector3_mul(&dir1,fac);
|
||||
gck_vector3_mul(&dir2,fac);
|
||||
|
||||
gck_vector3_add(&a,&mapvals.position,&v1);
|
||||
gck_vector3_sub(&b,&a,&v2);
|
||||
gck_vector3_add(&a,&a,&v2);
|
||||
gck_vector3_sub(&d,&mapvals.position,&v1);
|
||||
gck_vector3_sub(&d,&d,&v2);
|
||||
|
||||
c=b;
|
||||
|
||||
cx1=(gdouble)startx;
|
||||
cy1=(gdouble)starty;
|
||||
cx2=cx1+(gdouble)pw;
|
||||
cy2=cy1+(gdouble)ph;
|
||||
|
||||
for (cnt=0;cnt<=WIRESIZE;cnt++)
|
||||
{
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x1,&y1,&mapvals.viewpoint,&a);
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x2,&y2,&mapvals.viewpoint,&b);
|
||||
|
||||
if (gck_clip_line(&x1,&y1,&x2,&y2,cx1,cy1,cx2,cy2)==TRUE)
|
||||
{
|
||||
linetab[n].x1=(gint)(x1+0.5);
|
||||
linetab[n].y1=(gint)(y1+0.5);
|
||||
linetab[n].x2=(gint)(x2+0.5);
|
||||
linetab[n].y2=(gint)(y2+0.5);
|
||||
linetab[n].linewidth=1;
|
||||
linetab[n].linestyle=GDK_LINE_SOLID;
|
||||
gdk_gc_set_line_attributes(gc,linetab[n].linewidth,linetab[n].linestyle,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
|
||||
gdk_draw_line(previewarea->window,gc,linetab[n].x1,linetab[n].y1,linetab[n].x2,linetab[n].y2);
|
||||
n++;
|
||||
}
|
||||
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x1,&y1,&mapvals.viewpoint,&c);
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x2,&y2,&mapvals.viewpoint,&d);
|
||||
|
||||
if (gck_clip_line(&x1,&y1,&x2,&y2,cx1,cy1,cx2,cy2)==TRUE)
|
||||
{
|
||||
linetab[n].x1=(gint)(x1+0.5);
|
||||
linetab[n].y1=(gint)(y1+0.5);
|
||||
linetab[n].x2=(gint)(x2+0.5);
|
||||
linetab[n].y2=(gint)(y2+0.5);
|
||||
linetab[n].linewidth=1;
|
||||
linetab[n].linestyle=GDK_LINE_SOLID;
|
||||
gdk_gc_set_line_attributes(gc,linetab[n].linewidth,linetab[n].linestyle,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
|
||||
gdk_draw_line(previewarea->window,gc,linetab[n].x1,linetab[n].y1,linetab[n].x2,linetab[n].y2);
|
||||
n++;
|
||||
}
|
||||
|
||||
gck_vector3_sub(&a,&a,&dir1);
|
||||
gck_vector3_sub(&b,&b,&dir1);
|
||||
gck_vector3_add(&c,&c,&dir2);
|
||||
gck_vector3_add(&d,&d,&dir2);
|
||||
}
|
||||
|
||||
/* Mark end of lines */
|
||||
/* ================= */
|
||||
|
||||
linetab[n].x1=-1;
|
||||
}
|
||||
|
||||
void draw_wireframe_sphere(gint startx,gint starty,gint pw,gint ph)
|
||||
{
|
||||
GckVector3 p[2*(WIRESIZE+5)];
|
||||
gint cnt,cnt2,n=0;
|
||||
gdouble x1,y1,x2,y2,twopifac,cx1,cy1,cx2,cy2;
|
||||
|
||||
/* Compute wireframe points */
|
||||
/* ======================== */
|
||||
|
||||
twopifac=(2.0*M_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);
|
||||
gck_vector3_rotate(&p[cnt],gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
gck_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;
|
||||
gck_vector3_rotate(&p[cnt],gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
gck_vector3_add(&p[cnt],&p[cnt],&mapvals.position);
|
||||
}
|
||||
p[cnt]=p[WIRESIZE+1];
|
||||
cnt++;
|
||||
cnt2=cnt;
|
||||
|
||||
/* Find rotated axis */
|
||||
/* ================= */
|
||||
|
||||
gck_vector3_set(&p[cnt],0.0,-0.35,0.0);
|
||||
gck_vector3_rotate(&p[cnt],gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
p[cnt+1]=mapvals.position;
|
||||
|
||||
gck_vector3_set(&p[cnt+2],0.0,0.0,-0.35);
|
||||
gck_vector3_rotate(&p[cnt+2],gck_deg_to_rad(mapvals.alpha),
|
||||
gck_deg_to_rad(mapvals.beta),gck_deg_to_rad(mapvals.gamma));
|
||||
p[cnt+3]=mapvals.position;
|
||||
|
||||
p[cnt+4]=p[cnt];
|
||||
gck_vector3_mul(&p[cnt+4],-1.0);
|
||||
p[cnt+5]=p[cnt+1];
|
||||
|
||||
gck_vector3_add(&p[cnt],&p[cnt],&mapvals.position);
|
||||
gck_vector3_add(&p[cnt+2],&p[cnt+2],&mapvals.position);
|
||||
gck_vector3_add(&p[cnt+4],&p[cnt+4],&mapvals.position);
|
||||
|
||||
/* Draw the circles (equator and zero meridian) */
|
||||
/* ============================================ */
|
||||
|
||||
cx1=(gdouble)startx;
|
||||
cy1=(gdouble)starty;
|
||||
cx2=cx1+(gdouble)pw;
|
||||
cy2=cy1+(gdouble)ph;
|
||||
|
||||
for (cnt=0;cnt<cnt2-1;cnt++)
|
||||
{
|
||||
if (p[cnt].z>mapvals.position.z && p[cnt+1].z>mapvals.position.z)
|
||||
{
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x1,&y1,&mapvals.viewpoint,&p[cnt]);
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x2,&y2,&mapvals.viewpoint,&p[cnt+1]);
|
||||
|
||||
if (gck_clip_line(&x1,&y1,&x2,&y2,cx1,cy1,cx2,cy2)==TRUE)
|
||||
{
|
||||
linetab[n].x1=(gint)(x1+0.5);
|
||||
linetab[n].y1=(gint)(y1+0.5);
|
||||
linetab[n].x2=(gint)(x2+0.5);
|
||||
linetab[n].y2=(gint)(y2+0.5);
|
||||
linetab[n].linewidth=3;
|
||||
linetab[n].linestyle=GDK_LINE_SOLID;
|
||||
gdk_gc_set_line_attributes(gc,linetab[n].linewidth,linetab[n].linestyle,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
|
||||
gdk_draw_line(previewarea->window,gc,linetab[n].x1,linetab[n].y1,linetab[n].x2,linetab[n].y2);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the axis (pole to pole and center to zero meridian) */
|
||||
/* ======================================================== */
|
||||
|
||||
for (cnt=0;cnt<3;cnt++)
|
||||
{
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x1,&y1,&mapvals.viewpoint,&p[cnt2]);
|
||||
gck_3d_to_2d(startx,starty,pw,ph,&x2,&y2,&mapvals.viewpoint,&p[cnt2+1]);
|
||||
|
||||
if (gck_clip_line(&x1,&y1,&x2,&y2,cx1,cy1,cx2,cy2)==TRUE)
|
||||
{
|
||||
linetab[n].x1=(gint)(x1+0.5);
|
||||
linetab[n].y1=(gint)(y1+0.5);
|
||||
linetab[n].x2=(gint)(x2+0.5);
|
||||
linetab[n].y2=(gint)(y2+0.5);
|
||||
|
||||
if (p[cnt2].z<mapvals.position.z || p[cnt2+1].z<mapvals.position.z)
|
||||
{
|
||||
linetab[n].linewidth=1;
|
||||
linetab[n].linestyle=GDK_LINE_DOUBLE_DASH;
|
||||
}
|
||||
else
|
||||
{
|
||||
linetab[n].linewidth=3;
|
||||
linetab[n].linestyle=GDK_LINE_SOLID;
|
||||
}
|
||||
gdk_gc_set_line_attributes(gc,linetab[n].linewidth,linetab[n].linestyle,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
|
||||
gdk_draw_line(previewarea->window,gc,linetab[n].x1,linetab[n].y1,linetab[n].x2,linetab[n].y2);
|
||||
n++;
|
||||
}
|
||||
cnt2+=2;
|
||||
}
|
||||
|
||||
/* Mark end of lines */
|
||||
/* ================= */
|
||||
|
||||
linetab[n].x1=-1;
|
||||
}
|
||||
|
||||
void clear_wireframe(void)
|
||||
{
|
||||
gint n=0;
|
||||
|
||||
while (linetab[n].x1!=-1)
|
||||
{
|
||||
gdk_gc_set_line_attributes(gc,linetab[n].linewidth,linetab[n].linestyle,GDK_CAP_NOT_LAST,GDK_JOIN_MITER);
|
||||
gdk_draw_line(previewarea->window,gc,linetab[n].x1,linetab[n].y1,
|
||||
linetab[n].x2,linetab[n].y2);
|
||||
n++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef MAPOBJECTPREVIEWH
|
||||
#define MAPOBJECTPREVIEWH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gck/gck.h>
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "arcball.h"
|
||||
#include "mapobject_main.h"
|
||||
#include "mapobject_ui.h"
|
||||
#include "mapobject_image.h"
|
||||
#include "mapobject_apply.h"
|
||||
#include "mapobject_shade.h"
|
||||
|
||||
#define PREVIEW_WIDTH 200
|
||||
#define PREVIEW_HEIGHT 200
|
||||
|
||||
#define WIRESIZE 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint x1,y1,x2,y2;
|
||||
gint linewidth;
|
||||
GdkLineStyle linestyle;
|
||||
} line;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint x,y,w,h;
|
||||
GdkImage *image;
|
||||
} BackBuffer;
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern line linetab[];
|
||||
extern gdouble mat[3][4];
|
||||
extern gint lightx,lighty;
|
||||
extern BackBuffer backbuf;
|
||||
|
||||
/* Externally visible functions */
|
||||
/* ============================ */
|
||||
|
||||
extern void compute_preview (gint x,gint y,gint w,gint h,gint pw,gint ph);
|
||||
extern void draw_wireframe (gint startx,gint starty,gint pw,gint ph);
|
||||
extern void clear_wireframe (void);
|
||||
extern void draw_preview_image (gint docompute);
|
||||
extern void draw_preview_wireframe (void);
|
||||
extern gint check_light_hit (gint xpos,gint ypos);
|
||||
extern void update_light (gint xpos,gint ypos);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,413 @@
|
|||
/*****************/
|
||||
/* Shading stuff */
|
||||
/*****************/
|
||||
|
||||
#include "mapobject_shade.h"
|
||||
|
||||
gdouble bx1,by1,bx2,by2;
|
||||
get_ray_color_func get_ray_color;
|
||||
|
||||
/*****************/
|
||||
/* Phong shading */
|
||||
/*****************/
|
||||
|
||||
GckRGB phong_shade(GckVector3 *pos,GckVector3 *viewpoint,GckVector3 *normal,GckVector3 *light,
|
||||
GckRGB *diff_col,GckRGB *spec_col,gint type)
|
||||
{
|
||||
GckRGB ambientcolor,diffusecolor,specularcolor;
|
||||
gdouble NL,RV,dist;
|
||||
GckVector3 L,NN,V,N;
|
||||
|
||||
/* Compute ambient intensity */
|
||||
/* ========================= */
|
||||
|
||||
N=*normal;
|
||||
ambientcolor=*diff_col;
|
||||
gck_rgb_mul(&ambientcolor,mapvals.material.ambient_int);
|
||||
|
||||
/* Compute (N*L) term of Phong's equation */
|
||||
/* ====================================== */
|
||||
|
||||
if (type==POINT_LIGHT)
|
||||
gck_vector3_sub(&L,light,pos);
|
||||
else
|
||||
L=*light;
|
||||
|
||||
dist=gck_vector3_length(&L);
|
||||
|
||||
if (dist!=0.0)
|
||||
gck_vector3_mul(&L,1.0/dist);
|
||||
|
||||
NL=2.0*gck_vector3_inner_product(&N,&L);
|
||||
|
||||
if (NL>=0.0)
|
||||
{
|
||||
/* Compute (R*V)^alpha term of Phong's equation */
|
||||
/* ============================================ */
|
||||
|
||||
gck_vector3_sub(&V,viewpoint,pos);
|
||||
gck_vector3_normalize(&V);
|
||||
|
||||
gck_vector3_mul(&N,NL);
|
||||
gck_vector3_sub(&NN,&N,&L);
|
||||
RV=gck_vector3_inner_product(&NN,&V);
|
||||
RV=pow(RV,mapvals.material.highlight);
|
||||
|
||||
/* Compute diffuse and specular intensity contribution */
|
||||
/* =================================================== */
|
||||
|
||||
diffusecolor=*diff_col;
|
||||
gck_rgb_mul(&diffusecolor,mapvals.material.diffuse_ref);
|
||||
gck_rgb_mul(&diffusecolor,NL);
|
||||
|
||||
specularcolor=*spec_col;
|
||||
gck_rgb_mul(&specularcolor,mapvals.material.specular_ref);
|
||||
gck_rgb_mul(&specularcolor,RV);
|
||||
|
||||
gck_rgb_add(&diffusecolor,&specularcolor);
|
||||
gck_rgb_mul(&diffusecolor,mapvals.material.diffuse_int);
|
||||
gck_rgb_clamp(&diffusecolor);
|
||||
|
||||
gck_rgb_add(&ambientcolor,&diffusecolor);
|
||||
}
|
||||
|
||||
return(ambientcolor);
|
||||
}
|
||||
|
||||
gint plane_intersect(GckVector3 *dir,GckVector3 *viewp,GckVector3 *ipos,gdouble *u,gdouble *v)
|
||||
{
|
||||
static gdouble det,det1,det2,det3,t;
|
||||
|
||||
imat[0][0]=dir->x; imat[1][0]=dir->y; imat[2][0]=dir->z;
|
||||
|
||||
/* Compute determinant of the first 3x3 sub matrix (denominator) */
|
||||
/* ============================================================= */
|
||||
|
||||
det=imat[0][0]*imat[1][1]*imat[2][2]+imat[0][1]*imat[1][2]*imat[2][0]+
|
||||
imat[0][2]*imat[1][0]*imat[2][1]-imat[0][2]*imat[1][1]*imat[2][0]-
|
||||
imat[0][0]*imat[1][2]*imat[2][1]-imat[2][2]*imat[0][1]*imat[1][0];
|
||||
|
||||
/* If the determinant is non-zero, a intersection point exists */
|
||||
/* =========================================================== */
|
||||
|
||||
if (det!=0.0)
|
||||
{
|
||||
/* Now, lets compute the numerator determinants (wow ;) */
|
||||
/* ==================================================== */
|
||||
|
||||
det1=imat[0][3]*imat[1][1]*imat[2][2]+imat[0][1]*imat[1][2]*imat[2][3]+
|
||||
imat[0][2]*imat[1][3]*imat[2][1]-imat[0][2]*imat[1][1]*imat[2][3]-
|
||||
imat[1][2]*imat[2][1]*imat[0][3]-imat[2][2]*imat[0][1]*imat[1][3];
|
||||
|
||||
det2=imat[0][0]*imat[1][3]*imat[2][2]+imat[0][3]*imat[1][2]*imat[2][0]+
|
||||
imat[0][2]*imat[1][0]*imat[2][3]-imat[0][2]*imat[1][3]*imat[2][0]-
|
||||
imat[1][2]*imat[2][3]*imat[0][0]-imat[2][2]*imat[0][3]*imat[1][0];
|
||||
|
||||
det3=imat[0][0]*imat[1][1]*imat[2][3]+imat[0][1]*imat[1][3]*imat[2][0]+
|
||||
imat[0][3]*imat[1][0]*imat[2][1]-imat[0][3]*imat[1][1]*imat[2][0]-
|
||||
imat[1][3]*imat[2][1]*imat[0][0]-imat[2][3]*imat[0][1]*imat[1][0];
|
||||
|
||||
/* Now we have the simultanous solutions. Lets compute the unknowns */
|
||||
/* (skip u&v if t is <0, this means the intersection is behind us) */
|
||||
/* ================================================================ */
|
||||
|
||||
t=det1/det;
|
||||
|
||||
if (t>0.0)
|
||||
{
|
||||
*u=1.0+((det2/det)-0.5);
|
||||
*v=1.0+((det3/det)-0.5);
|
||||
|
||||
ipos->x=viewp->x+t*dir->x;
|
||||
ipos->y=viewp->y+t*dir->y;
|
||||
ipos->z=viewp->z+t*dir->z;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
/* These routines computes the color of the surface of the plane at a given point */
|
||||
/**********************************************************************************/
|
||||
|
||||
GckRGB get_ray_color_plane(GckVector3 *pos)
|
||||
{
|
||||
GckRGB color=background;
|
||||
static gint inside=FALSE;
|
||||
static GckVector3 ray,spos;
|
||||
static gdouble vx,vy;
|
||||
|
||||
/* Construct a line from our VP to the point */
|
||||
/* ========================================= */
|
||||
|
||||
gck_vector3_sub(&ray,pos,&mapvals.viewpoint);
|
||||
gck_vector3_normalize(&ray);
|
||||
|
||||
/* Check for intersection. This is a quasi ray-tracer. */
|
||||
/* =================================================== */
|
||||
|
||||
if (plane_intersect(&ray,&mapvals.viewpoint,&spos,&vx,&vy)==TRUE)
|
||||
{
|
||||
color=get_image_color(vx,vy,&inside);
|
||||
|
||||
if (color.a!=0.0 && inside==TRUE && mapvals.lightsource.type!=NO_LIGHT)
|
||||
{
|
||||
/* Compute shading at this point */
|
||||
/* ============================= */
|
||||
|
||||
color=phong_shade(&spos,&mapvals.viewpoint,&mapvals.normal,
|
||||
&mapvals.lightsource.position,&color,
|
||||
&mapvals.lightsource.color,mapvals.lightsource.type);
|
||||
|
||||
gck_rgb_clamp(&color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (color.a==0.0)
|
||||
color=background;
|
||||
|
||||
return(color);
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/* Given the NorthPole, Equator and a third vector (normal) compute */
|
||||
/* the conversion from spherical oordinates to image space coordinates */
|
||||
/***********************************************************************/
|
||||
|
||||
void sphere_to_image(GckVector3 *normal,gdouble *u,gdouble *v)
|
||||
{
|
||||
static gdouble alpha,fac;
|
||||
static GckVector3 cross_prod;
|
||||
|
||||
alpha=acos(-gck_vector3_inner_product(&mapvals.secondaxis,normal));
|
||||
|
||||
*v=alpha/M_PI;
|
||||
|
||||
if (*v==0.0 || *v==1.0) *u=0.0;
|
||||
else
|
||||
{
|
||||
fac=gck_vector3_inner_product(&mapvals.firstaxis,normal)/sin(alpha);
|
||||
|
||||
/* Make sure that we map to -1.0..1.0 (take care of rounding errors) */
|
||||
/* ================================================================= */
|
||||
|
||||
if (fac>1.0)
|
||||
fac=1.0;
|
||||
else if (fac<-1.0)
|
||||
fac=-1.0;
|
||||
|
||||
*u=acos(fac)/(2.0*M_PI);
|
||||
|
||||
cross_prod=gck_vector3_cross_product(&mapvals.secondaxis,&mapvals.firstaxis);
|
||||
|
||||
if (gck_vector3_inner_product(&cross_prod,normal)<0.0)
|
||||
*u=1.0-*u;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* Compute intersection point with sphere (if any) */
|
||||
/***************************************************/
|
||||
|
||||
gint sphere_intersect(GckVector3 *dir,GckVector3 *viewp,GckVector3 *spos1,GckVector3 *spos2)
|
||||
{
|
||||
static gdouble alpha,beta,tau,s1,s2,tmp;
|
||||
static GckVector3 t;
|
||||
|
||||
gck_vector3_sub(&t,&mapvals.position,viewp);
|
||||
|
||||
alpha=gck_vector3_inner_product(dir,&t);
|
||||
beta=gck_vector3_inner_product(&t,&t);
|
||||
|
||||
tau=alpha*alpha-beta+mapvals.radius*mapvals.radius;
|
||||
|
||||
if (tau>=0.0)
|
||||
{
|
||||
tau=sqrt(tau);
|
||||
s1=alpha+tau;
|
||||
s2=alpha-tau;
|
||||
|
||||
if (s2<s1)
|
||||
{
|
||||
tmp=s1;
|
||||
s1=s2;
|
||||
s2=tmp;
|
||||
}
|
||||
|
||||
spos1->x=viewp->x+s1*dir->x;
|
||||
spos1->y=viewp->y+s1*dir->y;
|
||||
spos1->z=viewp->z+s1*dir->z;
|
||||
spos2->x=viewp->x+s2*dir->x;
|
||||
spos2->y=viewp->y+s2*dir->y;
|
||||
spos2->z=viewp->z+s2*dir->z;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/***********************************************************************************/
|
||||
/* These routines computes the color of the surface of the sphere at a given point */
|
||||
/***********************************************************************************/
|
||||
|
||||
GckRGB get_ray_color_sphere(GckVector3 *pos)
|
||||
{
|
||||
GckRGB color=background;
|
||||
static GckRGB color2;
|
||||
static gint inside=FALSE;
|
||||
static GckVector3 normal,ray,spos1,spos2;
|
||||
static gdouble vx,vy;
|
||||
|
||||
/* Check if ray is within the bounding box */
|
||||
/* ======================================= */
|
||||
|
||||
if (pos->x<bx1 || pos->x>bx2 || pos->y<by1 || pos->y>by2)
|
||||
return(color);
|
||||
|
||||
/* Construct a line from our VP to the point */
|
||||
/* ========================================= */
|
||||
|
||||
gck_vector3_sub(&ray,pos,&mapvals.viewpoint);
|
||||
gck_vector3_normalize(&ray);
|
||||
|
||||
/* Check for intersection. This is a quasi ray-tracer. */
|
||||
/* =================================================== */
|
||||
|
||||
if (sphere_intersect(&ray,&mapvals.viewpoint,&spos1,&spos2)==TRUE)
|
||||
{
|
||||
/* Compute spherical to rectangular mapping */
|
||||
/* ======================================== */
|
||||
|
||||
gck_vector3_sub(&normal,&spos1,&mapvals.position);
|
||||
gck_vector3_normalize(&normal);
|
||||
sphere_to_image(&normal,&vx,&vy);
|
||||
color=get_image_color(vx,vy,&inside);
|
||||
|
||||
/* Check for total transparency... */
|
||||
/* =============================== */
|
||||
|
||||
if (color.a<1.0)
|
||||
{
|
||||
/* Hey, we can see through here! */
|
||||
/* Lets see what's on the other side.. */
|
||||
/* =================================== */
|
||||
|
||||
color=phong_shade(&spos1,
|
||||
&mapvals.viewpoint,
|
||||
&normal,
|
||||
&mapvals.lightsource.position,
|
||||
&color,
|
||||
&mapvals.lightsource.color,
|
||||
mapvals.lightsource.type);
|
||||
|
||||
gck_rgba_clamp(&color);
|
||||
|
||||
gck_vector3_sub(&normal,&spos2,&mapvals.position);
|
||||
gck_vector3_normalize(&normal);
|
||||
sphere_to_image(&normal,&vx,&vy);
|
||||
color2=get_image_color(vx,vy,&inside);
|
||||
|
||||
/* Make the normal point inwards */
|
||||
/* ============================= */
|
||||
|
||||
gck_vector3_mul(&normal,-1.0);
|
||||
|
||||
color2=phong_shade(&spos2,
|
||||
&mapvals.viewpoint,
|
||||
&normal,
|
||||
&mapvals.lightsource.position,
|
||||
&color2,
|
||||
&mapvals.lightsource.color,
|
||||
mapvals.lightsource.type);
|
||||
|
||||
gck_rgba_clamp(&color2);
|
||||
|
||||
if (mapvals.transparent_background==FALSE && color2.a<1.0)
|
||||
{
|
||||
color2.r = (color2.r*color2.a)+(background.r*(1.0-color2.a));
|
||||
color2.g = (color2.g*color2.a)+(background.g*(1.0-color2.a));
|
||||
color2.b = (color2.b*color2.a)+(background.b*(1.0-color2.a));
|
||||
color2.a = 1.0;
|
||||
}
|
||||
|
||||
/* Compute a mix of the first and second colors */
|
||||
/* ============================================ */
|
||||
|
||||
color.r = color.r*color2.r;
|
||||
color.g = color.g*color2.g;
|
||||
color.b = color.b*color2.b;
|
||||
color.a = color.a+color2.a;
|
||||
|
||||
gck_rgba_clamp(&color);
|
||||
}
|
||||
else if (color.a!=0.0 && inside==TRUE && mapvals.lightsource.type!=NO_LIGHT)
|
||||
{
|
||||
/* Compute shading at this point */
|
||||
/* ============================= */
|
||||
|
||||
color=phong_shade(&spos1,
|
||||
&mapvals.viewpoint,
|
||||
&normal,
|
||||
&mapvals.lightsource.position,
|
||||
&color,
|
||||
&mapvals.lightsource.color,
|
||||
mapvals.lightsource.type);
|
||||
|
||||
gck_rgba_clamp(&color);
|
||||
}
|
||||
}
|
||||
|
||||
if (color.a==0.0)
|
||||
color=background;
|
||||
|
||||
return(color);
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* Transform the corners of the bounding box to 2D */
|
||||
/***************************************************/
|
||||
|
||||
void compute_bounding_box(void)
|
||||
{
|
||||
GckVector3 p1,p2;
|
||||
gdouble t;
|
||||
GckVector3 dir;
|
||||
|
||||
p1=mapvals.position;
|
||||
p1.x-=(mapvals.radius+0.01);
|
||||
p1.y-=(mapvals.radius+0.01);
|
||||
|
||||
p2=mapvals.position;
|
||||
p2.x+=(mapvals.radius+0.01);
|
||||
p2.y+=(mapvals.radius+0.01);
|
||||
|
||||
gck_vector3_sub(&dir,&p1,&mapvals.viewpoint);
|
||||
gck_vector3_normalize(&dir);
|
||||
|
||||
if (dir.z!=0.0)
|
||||
{
|
||||
t=(-1.0*mapvals.viewpoint.z)/dir.z;
|
||||
p1.x=(mapvals.viewpoint.x+t*dir.x);
|
||||
p1.y=(mapvals.viewpoint.y+t*dir.y);
|
||||
}
|
||||
|
||||
gck_vector3_sub(&dir,&p2,&mapvals.viewpoint);
|
||||
gck_vector3_normalize(&dir);
|
||||
|
||||
if (dir.z!=0.0)
|
||||
{
|
||||
t=(-1.0*mapvals.viewpoint.z)/dir.z;
|
||||
p2.x=(mapvals.viewpoint.x+t*dir.x);
|
||||
p2.y=(mapvals.viewpoint.y+t*dir.y);
|
||||
}
|
||||
|
||||
bx1=p1.x;
|
||||
by1=p1.y;
|
||||
bx2=p2.x;
|
||||
by2=p2.y;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef MAPOBJECTSHADEH
|
||||
#define MAPOBJECTSHADEH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gck/gck.h>
|
||||
|
||||
#include "mapobject_main.h"
|
||||
#include "mapobject_image.h"
|
||||
|
||||
typedef GckRGB (*get_ray_color_func)(GckVector3 *pos);
|
||||
|
||||
extern get_ray_color_func get_ray_color;
|
||||
extern GckRGB get_ray_color_plane (GckVector3 *pos);
|
||||
extern GckRGB get_ray_color_sphere (GckVector3 *pos);
|
||||
extern void compute_bounding_box (void);
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,30 @@
|
|||
#ifndef MAPOBJECTUIH
|
||||
#define MAPOBJECTUIH
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gck/gck.h>
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "arcball.h"
|
||||
#include "mapobject_main.h"
|
||||
#include "mapobject_image.h"
|
||||
#include "mapobject_apply.h"
|
||||
#include "mapobject_preview.h"
|
||||
|
||||
/* Externally visible variables */
|
||||
/* ============================ */
|
||||
|
||||
extern GckApplicationWindow *appwin;
|
||||
|
||||
extern GdkGC *gc;
|
||||
extern GtkWidget *previewarea;
|
||||
|
||||
/* Externally visible functions */
|
||||
/* ============================ */
|
||||
|
||||
extern void create_main_dialog(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,75 @@
|
|||
/* XPM */
|
||||
char * specref1_xpm[] = {
|
||||
"32 32 40 1",
|
||||
" c None",
|
||||
". c #A699A699A699",
|
||||
"X c #A699A289A699",
|
||||
"o c #965896589658",
|
||||
"O c #BEFBBEFBBEFB",
|
||||
"+ c #CF3CCB2BCF3C",
|
||||
"@ c #C71BC71BC71B",
|
||||
"# c #C71BC30BC71B",
|
||||
"$ c #B6DAB6DAB6DA",
|
||||
"% c #8E388E388E38",
|
||||
"& c #69A669A669A6",
|
||||
"* c #D75CD75CD75C",
|
||||
"= c #DF7DDB6CDF7D",
|
||||
"- c #CF3CCF3CCF3C",
|
||||
"; c #965892489658",
|
||||
": c #DF7DDF7DDF7D",
|
||||
"> c #E79DE38DE79D",
|
||||
", c #D75CD34CD75C",
|
||||
"< c #AEBAAEBAAEBA",
|
||||
"1 c #9E799E799E79",
|
||||
"2 c #861786178617",
|
||||
"3 c #596559655965",
|
||||
"4 c #E79DE79DE79D",
|
||||
"5 c #B6DAB2CAB6DA",
|
||||
"6 c #71C671C671C6",
|
||||
"7 c #492449244924",
|
||||
"8 c #71C675D671C6",
|
||||
"9 c #514455555144",
|
||||
"0 c #BEFBBAEABEFB",
|
||||
"q c #AEBAAAAAAEBA",
|
||||
"w c #9E799A699E79",
|
||||
"e c #8E388A288E38",
|
||||
"r c #49244D344924",
|
||||
"t c #861782078617",
|
||||
"y c #69A66DB669A6",
|
||||
"u c #79E779E779E7",
|
||||
"i c #618565956185",
|
||||
"p c #514451445144",
|
||||
"a c #618561856185",
|
||||
"s c #410345144103",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .Xo ",
|
||||
" .O+@#$.%& ",
|
||||
" $*==*-#$.;& ",
|
||||
" $=:>:=,+O<123 ",
|
||||
" .*:>4>=*+O5X%67 ",
|
||||
" O=>4>>=,+O5X%89 ",
|
||||
" +=:>>:*-@0<1%83 ",
|
||||
" .@*===*,+#$qwe83r ",
|
||||
" X#-,*,-+#0<Xoty9r ",
|
||||
" o$#+++@#05.weuipr ",
|
||||
" .$OOO0$<.1%ty3r ",
|
||||
" %.<55<qXw%t8ap7 ",
|
||||
" &;1XX1woet8iprs ",
|
||||
" &2%%%etuyaprs ",
|
||||
" 36888yi3prs ",
|
||||
" 79339pr7s ",
|
||||
" rrr ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -0,0 +1,79 @@
|
|||
/* XPM */
|
||||
char * specref2_xpm[] = {
|
||||
"32 32 44 1",
|
||||
" c None",
|
||||
". c #A699A699A699",
|
||||
"X c #A699A289A699",
|
||||
"o c #965896589658",
|
||||
"O c #BEFBBEFBBEFB",
|
||||
"+ c #CF3CCB2BCF3C",
|
||||
"@ c #C71BC71BC71B",
|
||||
"# c #C71BC30BC71B",
|
||||
"$ c #B6DAB6DAB6DA",
|
||||
"% c #8E388E388E38",
|
||||
"& c #69A669A669A6",
|
||||
"* c #D75CD75CD75C",
|
||||
"= c #DF7DDB6CDF7D",
|
||||
"- c #CF3CCF3CCF3C",
|
||||
"; c #965892489658",
|
||||
": c #DF7DDF7DDF7D",
|
||||
"> c #E79DE38DE79D",
|
||||
", c #D75CD34CD75C",
|
||||
"< c #AEBAAEBAAEBA",
|
||||
"1 c #9E799E799E79",
|
||||
"2 c #861786178617",
|
||||
"3 c #596559655965",
|
||||
"4 c #E79DE79DE79D",
|
||||
"5 c #EFBEEFBEEFBE",
|
||||
"6 c #B6DAB2CAB6DA",
|
||||
"7 c #71C671C671C6",
|
||||
"8 c #492449244924",
|
||||
"9 c #FFFFFBEEFFFF",
|
||||
"0 c #FFFFFFFFFFFF",
|
||||
"q c #71C675D671C6",
|
||||
"w c #514455555144",
|
||||
"e c #EFBEEBADEFBE",
|
||||
"r c #BEFBBAEABEFB",
|
||||
"t c #AEBAAAAAAEBA",
|
||||
"y c #9E799A699E79",
|
||||
"u c #8E388A288E38",
|
||||
"i c #49244D344924",
|
||||
"p c #861782078617",
|
||||
"a c #69A66DB669A6",
|
||||
"s c #79E779E779E7",
|
||||
"d c #618565956185",
|
||||
"f c #514451445144",
|
||||
"g c #618561856185",
|
||||
"h c #410345144103",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .Xo ",
|
||||
" .O+@#$.%& ",
|
||||
" $*==*-#$.;& ",
|
||||
" $=:>:=,+O<123 ",
|
||||
" .*:4454*+O6X%78 ",
|
||||
" O=>4900>+O6X%qw ",
|
||||
" +=:5000e+r<1%q3 ",
|
||||
" .@*=4009=#$tyuq3i ",
|
||||
" X#-,*>e=@r<Xopawi ",
|
||||
" o$#++++#r6.yusdfi ",
|
||||
" .$OOOr$<.1%pa3i ",
|
||||
" %.<66<tXy%pqgf8 ",
|
||||
" &;1XX1youpqdfih ",
|
||||
" &2%%%upsagfih ",
|
||||
" 37qqqad3fih ",
|
||||
" 8w33wfi8h ",
|
||||
" iii ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
Loading…
Reference in New Issue