Files
test2/source/blender/src/transform.c

4748 lines
105 KiB
C
Raw Normal View History

/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef WIN32
#include <unistd.h>
#else
#include <io.h>
#endif
#include "MEM_guardedalloc.h"
#include "DNA_armature_types.h"
#include "DNA_action_types.h" /* for some special action-editor settings */
#include "DNA_constraint_types.h"
#include "DNA_ipo_types.h" /* some silly ipo flag */
#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h" /* PET modes */
#include "DNA_screen_types.h" /* area dimensions */
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "DNA_space_types.h"
#include "BIF_editview.h" /* arrows_move_cursor */
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_mywindow.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_space.h" /* undo */
#include "BIF_toets.h" /* persptoetsen */
#include "BIF_mywindow.h" /* warp_pointer */
#include "BIF_toolbox.h" /* notice */
#include "BIF_editmesh.h"
#include "BIF_editsima.h"
#include "BIF_editparticle.h"
#include "BIF_drawimage.h" /* uvco_to_areaco_noclip */
#include "BIF_editaction.h"
#include "BKE_action.h" /* get_action_frame */
Point Cache Refactoring ======================= Caching and Baking: - The point cache is now cleared on DAG_object_flush_update(), and not cleared for time dependency graph updates. - There is now a Bake button instead of Protect. Also cache start and end frames were added to softbody and particles. - The cloth autoprotect feature was removed. - The Ctrl+B menu now also bakes cloth and particles next to softbody and fluids. Additionally there are now frree bake and free cache menu entries. - The point cache api has been changed. There is now a PTCacheID struct for each point cache type that can be filled and then used to call the point cache functions. - PointCache struct was added to DNA and is automatically allocated for each physics type. - Soft body now supports Bake Editing just like cloth. - Tried to make the systems deal consistently with time ipo's and offsets. Still not sure it all works correct, but too complicated to solve completely now. Library Linking: - Added some more warnings to prevent editing settings on library linked objects. - Linked objects now read from the cache located next to the original library file, and never write to it. This restores old behavior for softbodies. For local simulation the mesh and not the object should be linked. - Dupligroups and proxies can't create local point caches at the moment, how to implement that I'm not sure. We probably need a proxy point cache for that to work (ugh). Physics UI: - Renamed deflection panel to collision for consistency and reorganized the buttons. Also removed some softbody collision buttons from the softbody panel that were duplicated in this panel for cloth. - Tweaked field panel buttons to not jump around when changing options. - Tabbing e.g. Soft Body Collision into the Soft Body panel, it now only shows Collision to make the panel names readable. - I tried to make enabled/disabling physics more consistent, since all three system did things different. Now the two modifier buttons to enable the modifier for the viewport and rendering are also duplicated in the physics panels. Toggling the Soft Body and Cloth buttons now both remove their modifiers. - Fixed modifier error drawing glitch. Particles: - Particles are now recalculated more often than before. Previously it did partial updates based on the changes, but that doesn't work well with DAG_object_flush_update() .. - Fixed memory leak loading keyed particle system. Now keys are not written to file anymore but always created after loading. - Make particle threads work with autothreads. Continue Physics: - The timeline play now has a Continue Physics option in the playback menu, which keeps the simulations going without writing them to the cache. - This doesn't always work that well, some changes are not immediately updated, but this can be improved later. Still it's fun to get a feel for the physics. Todo: - Point cache can get out of sync with and undo and changing a file without saving it. - Change the point cache file format to store a version (so old point cache files can be either converted or at least ignored), and to do correct endian conversion. - Menu item and/or buttons for Ctrl+B. - A system("rm ..") was changed to remove() since the former is very slow for clearing point caches. These system() calls were already giving trouble in a bug in the tracker, but really most use of this system("") should be changed and tested. - The Soft Body Collision and Clot Collision panel titles don't mention there's point cache settings there too, doing that makes them unreadable with the default panel setup.. but may need to make the names longer anyway.
2008-04-10 11:39:20 +00:00
#include "BKE_bad_level_calls.h"/* popmenu and error */
#include "BKE_bmesh.h"
#include "BKE_constraint.h"
#include "BKE_global.h"
#include "BKE_particle.h"
Point Cache Refactoring ======================= Caching and Baking: - The point cache is now cleared on DAG_object_flush_update(), and not cleared for time dependency graph updates. - There is now a Bake button instead of Protect. Also cache start and end frames were added to softbody and particles. - The cloth autoprotect feature was removed. - The Ctrl+B menu now also bakes cloth and particles next to softbody and fluids. Additionally there are now frree bake and free cache menu entries. - The point cache api has been changed. There is now a PTCacheID struct for each point cache type that can be filled and then used to call the point cache functions. - PointCache struct was added to DNA and is automatically allocated for each physics type. - Soft body now supports Bake Editing just like cloth. - Tried to make the systems deal consistently with time ipo's and offsets. Still not sure it all works correct, but too complicated to solve completely now. Library Linking: - Added some more warnings to prevent editing settings on library linked objects. - Linked objects now read from the cache located next to the original library file, and never write to it. This restores old behavior for softbodies. For local simulation the mesh and not the object should be linked. - Dupligroups and proxies can't create local point caches at the moment, how to implement that I'm not sure. We probably need a proxy point cache for that to work (ugh). Physics UI: - Renamed deflection panel to collision for consistency and reorganized the buttons. Also removed some softbody collision buttons from the softbody panel that were duplicated in this panel for cloth. - Tweaked field panel buttons to not jump around when changing options. - Tabbing e.g. Soft Body Collision into the Soft Body panel, it now only shows Collision to make the panel names readable. - I tried to make enabled/disabling physics more consistent, since all three system did things different. Now the two modifier buttons to enable the modifier for the viewport and rendering are also duplicated in the physics panels. Toggling the Soft Body and Cloth buttons now both remove their modifiers. - Fixed modifier error drawing glitch. Particles: - Particles are now recalculated more often than before. Previously it did partial updates based on the changes, but that doesn't work well with DAG_object_flush_update() .. - Fixed memory leak loading keyed particle system. Now keys are not written to file anymore but always created after loading. - Make particle threads work with autothreads. Continue Physics: - The timeline play now has a Continue Physics option in the playback menu, which keeps the simulations going without writing them to the cache. - This doesn't always work that well, some changes are not immediately updated, but this can be improved later. Still it's fun to get a feel for the physics. Todo: - Point cache can get out of sync with and undo and changing a file without saving it. - Change the point cache file format to store a version (so old point cache files can be either converted or at least ignored), and to do correct endian conversion. - Menu item and/or buttons for Ctrl+B. - A system("rm ..") was changed to remove() since the former is very slow for clearing point caches. These system() calls were already giving trouble in a bug in the tracker, but really most use of this system("") should be changed and tested. - The Soft Body Collision and Clot Collision panel titles don't mention there's point cache settings there too, doing that makes them unreadable with the default panel setup.. but may need to make the names longer anyway.
2008-04-10 11:39:20 +00:00
#include "BKE_pointcache.h"
#include "BKE_utildefines.h"
#include "BSE_drawipo.h"
#include "BSE_editnla_types.h" /* for NLAWIDTH */
#include "BSE_editaction_types.h"
#include "BSE_time.h"
#include "BSE_view.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "PIL_time.h" /* sleep */
#include "blendef.h"
#include "mydevice.h"
#include "transform.h"
/* GLOBAL VARIABLE THAT SHOULD MOVED TO SCREEN MEMBER OR SOMETHING */
TransInfo Trans = {TFM_INIT, 0}; // enforce init on first usage
/******************************** Helper functions ************************************/
/* GLOBAL Wrapper Fonctions */
void BIF_drawSnap()
{
drawSnapping(&Trans);
}
/* ************************** Dashed help line **************************** */
/* bad frontbuffer call... because it is used in transform after force_draw() */
static void helpline(TransInfo *t, float *vec)
{
float vecrot[3], cent[2];
short mval[2];
VECCOPY(vecrot, vec);
if(t->flag & T_EDIT) {
Object *ob=G.obedit;
if(ob) Mat4MulVecfl(ob->obmat, vecrot);
}
else if(t->flag & T_POSE) {
Object *ob=t->poseobj;
if(ob) Mat4MulVecfl(ob->obmat, vecrot);
}
getmouseco_areawin(mval);
projectFloatView(t, vecrot, cent); // no overflow in extreme cases
persp(PERSP_WIN);
glDrawBuffer(GL_FRONT);
BIF_ThemeColor(TH_WIRE);
setlinestyle(3);
glBegin(GL_LINE_STRIP);
glVertex2sv(mval);
glVertex2fv(cent);
glEnd();
setlinestyle(0);
persp(PERSP_VIEW);
bglFlush(); // flush display for frontbuffer
glDrawBuffer(GL_BACK);
}
=== Custom Transform Orientation === Custom Orientations can be added with Ctrl-Shift-C (hotkey suggestions are welcomed), this adds and select the new alignment. Custom Orientations can also be added, deleted, selected from the Transform Orientations panel (View -> Transform Orientations). Standard orientations (global, local, normal, view) can also be selected from this panel. If you plan on using only a single custom orientation and don't really need a list, I suggest you use the hotkey as it adds and selects at the same time. Custom Orientations are save in the scene and are selected per 3D view (like normal orientation). Adding from an object, the orientation is a normalized version of the object's orientation. Adding from mesh data, a single element (vertex, edge, face) must be selected in its respective selection mode. Vertex orientation Z-axis is based on the normal, edge Z-axis on the edge itself (X-axis is on the XoY plane when possible, Y-axis is perpendicular to the rest). Face orientation Z-axis is the face normal, X-axis is perpendicular to the first edge, Y-axis is perpendicular to the rest. (More logical orientations can be suggested). I plan to add: 2 vertice (connected or not) => edge orientation , 3 vertice = face orientation Differences from the patch: - orientations no longer link back to the object they came from, everything is copy on creation. - orientations are overwritten based on name (if you add an orientation with the same name as one that already exists, it overwrites the old one)
2008-01-13 18:24:09 +00:00
/* ************************** INPUT FROM MOUSE *************************** */
float InputScaleRatio(TransInfo *t, short mval[2]) {
float ratio, dx, dy;
if(t->flag & T_SHIFT_MOD) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
dx = (float)(t->center2d[0] - t->shiftmval[0]);
dy = (float)(t->center2d[1] - t->shiftmval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
dx= (float)(t->center2d[0] - mval[0]);
dy= (float)(t->center2d[1] - mval[1]);
ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
}
else {
dx = (float)(t->center2d[0] - mval[0]);
dy = (float)(t->center2d[1] - mval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
}
return ratio;
}
float InputHorizontalRatio(TransInfo *t, short mval[2]) {
float x, pad;
pad = curarea->winx / 10;
if (t->flag & T_SHIFT_MOD) {
/* deal with Shift key by adding motion / 10 to motion before shift press */
x = t->shiftmval[0] + (float)(mval[0] - t->shiftmval[0]) / 10.0f;
}
else {
x = mval[0];
}
return (x - pad) / (curarea->winx - 2 * pad);
}
float InputHorizontalAbsolute(TransInfo *t, short mval[2]) {
float vec[3];
if(t->flag & T_SHIFT_MOD) {
float dvec[3];
/* calculate the main translation and the precise one separate */
convertViewVec(t, dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1]));
VecMulf(dvec, 0.1f);
convertViewVec(t, t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1]));
VecAddf(t->vec, t->vec, dvec);
}
else {
convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
}
Projf(vec, t->vec, t->viewinv[0]);
return Inpf(t->viewinv[0], vec) * 2.0f;
}
float InputVerticalRatio(TransInfo *t, short mval[2]) {
float y, pad;
pad = curarea->winy / 10;
if (t->flag & T_SHIFT_MOD) {
/* deal with Shift key by adding motion / 10 to motion before shift press */
y = t->shiftmval[1] + (float)(mval[1] - t->shiftmval[1]) / 10.0f;
}
else {
y = mval[0];
}
return (y - pad) / (curarea->winy - 2 * pad);
}
float InputVerticalAbsolute(TransInfo *t, short mval[2]) {
float vec[3];
if(t->flag & T_SHIFT_MOD) {
float dvec[3];
/* calculate the main translation and the precise one separate */
convertViewVec(t, dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1]));
VecMulf(dvec, 0.1f);
convertViewVec(t, t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1]));
VecAddf(t->vec, t->vec, dvec);
}
else {
convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
}
Projf(vec, t->vec, t->viewinv[1]);
return Inpf(t->viewinv[1], vec) * 2.0f;
}
float InputDeltaAngle(TransInfo *t, short mval[2])
{
double dx2 = mval[0] - t->center2d[0];
double dy2 = mval[1] - t->center2d[1];
double B = sqrt(dx2*dx2+dy2*dy2);
double dx1 = t->imval[0] - t->center2d[0];
double dy1 = t->imval[1] - t->center2d[1];
double A = sqrt(dx1*dx1+dy1*dy1);
double dx3 = mval[0] - t->imval[0];
double dy3 = mval[1] - t->imval[1];
/* use doubles here, to make sure a "1.0" (no rotation) doesnt become 9.999999e-01, which gives 0.02 for acos */
double deler = ((dx1*dx1+dy1*dy1)+(dx2*dx2+dy2*dy2)-(dx3*dx3+dy3*dy3))
/ (2.0 * (A*B?A*B:1.0));
/* (A*B?A*B:1.0f) this takes care of potential divide by zero errors */
float dphi;
dphi = saacos((float)deler);
if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
/* If the angle is zero, because of lack of precision close to the 1.0 value in acos
* approximate the angle with the oposite side of the normalized triangle
* This is a good approximation here since the smallest acos value seems to be around
* 0.02 degree and lower values don't even have a 0.01% error compared to the approximation
* */
if (dphi == 0)
{
double dx, dy;
dx2 /= A;
dy2 /= A;
dx1 /= B;
dy1 /= B;
dx = dx1 - dx2;
dy = dy1 - dy2;
dphi = sqrt(dx*dx + dy*dy);
if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
}
if(t->flag & T_SHIFT_MOD) dphi = dphi/30.0f;
/* if no delta angle, don't update initial position */
if (dphi != 0)
{
t->imval[0] = mval[0];
t->imval[1] = mval[1];
}
return dphi;
}
/* ************************** SPACE DEPENDANT CODE **************************** */
void setTransformViewMatrices(TransInfo *t)
{
if(t->spacetype==SPACE_VIEW3D) {
Mat4CpyMat4(t->viewmat, G.vd->viewmat);
Mat4CpyMat4(t->viewinv, G.vd->viewinv);
Mat4CpyMat4(t->persmat, G.vd->persmat);
Mat4CpyMat4(t->persinv, G.vd->persinv);
t->persp= G.vd->persp;
}
else {
Mat4One(t->viewmat);
Mat4One(t->viewinv);
Mat4One(t->persmat);
Mat4One(t->persinv);
t->persp = V3D_ORTHO;
}
calculateCenter2D(t);
}
void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
{
if (t->spacetype==SPACE_VIEW3D) {
window_to_3d(vec, dx, dy);
}
else if(t->spacetype==SPACE_IMAGE) {
float divx, divy, aspx, aspy;
transform_aspect_ratio_tface_uv(&aspx, &aspy);
divx= G.v2d->mask.xmax-G.v2d->mask.xmin;
divy= G.v2d->mask.ymax-G.v2d->mask.ymin;
vec[0]= aspx*(G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/divx;
vec[1]= aspy*(G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/divy;
vec[2]= 0.0f;
}
else if(t->spacetype==SPACE_IPO) {
float divx, divy;
divx= G.v2d->mask.xmax-G.v2d->mask.xmin;
divy= G.v2d->mask.ymax-G.v2d->mask.ymin;
vec[0]= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx) / (divx);
vec[1]= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy) / (divy);
vec[2]= 0.0f;
}
}
void projectIntView(TransInfo *t, float *vec, int *adr)
{
if (t->spacetype==SPACE_VIEW3D) {
project_int_noclip(vec, adr);
}
else if(t->spacetype==SPACE_IMAGE) {
float aspx, aspy, v[2];
transform_aspect_ratio_tface_uv(&aspx, &aspy);
v[0]= vec[0]/aspx;
v[1]= vec[1]/aspy;
uvco_to_areaco_noclip(v, adr);
}
else if(t->spacetype==SPACE_IPO) {
short out[2] = {0.0f, 0.0f};
ipoco_to_areaco(G.v2d, vec, out);
adr[0]= out[0];
adr[1]= out[1];
}
}
void projectFloatView(TransInfo *t, float *vec, float *adr)
{
if (t->spacetype==SPACE_VIEW3D) {
project_float_noclip(vec, adr);
}
else if(t->spacetype==SPACE_IMAGE) {
int a[2];
projectIntView(t, vec, a);
adr[0]= a[0];
adr[1]= a[1];
}
else if(t->spacetype==SPACE_IPO) {
int a[2];
projectIntView(t, vec, a);
adr[0]= a[0];
adr[1]= a[1];
}
}
void convertVecToDisplayNum(float *vec, float *num)
{
TransInfo *t= BIF_GetTransInfo();
VECCOPY(num, vec);
if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) {
float aspx, aspy;
if((G.sima->flag & SI_COORDFLOATS)==0) {
int width, height;
transform_width_height_tface_uv(&width, &height);
num[0] *= width;
num[1] *= height;
}
transform_aspect_ratio_tface_uv(&aspx, &aspy);
num[0] /= aspx;
num[1] /= aspy;
}
}
void convertDisplayNumToVec(float *num, float *vec)
{
TransInfo *t= BIF_GetTransInfo();
VECCOPY(vec, num);
if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) {
float aspx, aspy;
if((G.sima->flag & SI_COORDFLOATS)==0) {
int width, height;
transform_width_height_tface_uv(&width, &height);
vec[0] /= width;
vec[1] /= height;
}
transform_aspect_ratio_tface_uv(&aspx, &aspy);
vec[0] *= aspx;
vec[1] *= aspy;
}
}
static void viewRedrawForce(TransInfo *t)
{
if (t->spacetype == SPACE_VIEW3D)
force_draw(0);
else if (t->spacetype==SPACE_IMAGE) {
if (G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
else force_draw(0);
}
else if (t->spacetype == SPACE_ACTION) {
if (G.saction->lock) {
short context;
/* we ignore the pointer this function returns (not needed) */
get_action_context(&context);
if (context == ACTCONT_ACTION)
force_draw_plus(SPACE_VIEW3D, 0);
else if (context == ACTCONT_SHAPEKEY)
force_draw_all(0);
else
force_draw(0);
}
else {
force_draw(0);
}
}
else if (t->spacetype == SPACE_NLA) {
if (G.snla->lock)
force_draw_all(0);
else
force_draw(0);
}
else if (t->spacetype == SPACE_IPO) {
/* update realtime */
if (G.sipo->lock) {
if (G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE)
force_draw_plus(SPACE_BUTS, 0);
else if (G.sipo->blocktype==ID_CA)
force_draw_plus(SPACE_VIEW3D, 0);
else if (G.sipo->blocktype==ID_KE)
force_draw_plus(SPACE_VIEW3D, 0);
else if (G.sipo->blocktype==ID_PO)
force_draw_plus(SPACE_VIEW3D, 0);
else if (G.sipo->blocktype==ID_OB)
force_draw_plus(SPACE_VIEW3D, 0);
else if (G.sipo->blocktype==ID_SEQ)
force_draw_plus(SPACE_SEQ, 0);
else
force_draw(0);
}
else {
force_draw(0);
}
}
}
static void viewRedrawPost(TransInfo *t)
{
if(t->spacetype==SPACE_VIEW3D) {
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWVIEW3D, 0);
}
else if(t->spacetype==SPACE_IMAGE) {
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
}
else if(ELEM3(t->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_IPO)) {
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWTIME, 0);
allqueue(REDRAWBUTSOBJECT, 0);
}
scrarea_queue_headredraw(curarea);
}
/* ************************** TRANSFORMATIONS **************************** */
void BIF_selectOrientation() {
short val;
char *str_menu = BIF_menustringTransformOrientation("Orientation");
=== Custom Transform Orientation === Custom Orientations can be added with Ctrl-Shift-C (hotkey suggestions are welcomed), this adds and select the new alignment. Custom Orientations can also be added, deleted, selected from the Transform Orientations panel (View -> Transform Orientations). Standard orientations (global, local, normal, view) can also be selected from this panel. If you plan on using only a single custom orientation and don't really need a list, I suggest you use the hotkey as it adds and selects at the same time. Custom Orientations are save in the scene and are selected per 3D view (like normal orientation). Adding from an object, the orientation is a normalized version of the object's orientation. Adding from mesh data, a single element (vertex, edge, face) must be selected in its respective selection mode. Vertex orientation Z-axis is based on the normal, edge Z-axis on the edge itself (X-axis is on the XoY plane when possible, Y-axis is perpendicular to the rest). Face orientation Z-axis is the face normal, X-axis is perpendicular to the first edge, Y-axis is perpendicular to the rest. (More logical orientations can be suggested). I plan to add: 2 vertice (connected or not) => edge orientation , 3 vertice = face orientation Differences from the patch: - orientations no longer link back to the object they came from, everything is copy on creation. - orientations are overwritten based on name (if you add an orientation with the same name as one that already exists, it overwrites the old one)
2008-01-13 18:24:09 +00:00
val= pupmenu(str_menu);
MEM_freeN(str_menu);
if(val >= 0) {
G.vd->twmode = val;
}
}
static void view_editmove(unsigned short event)
{
int refresh = 0;
/* Regular: Zoom in */
/* Shift: Scroll up */
/* Ctrl: Scroll right */
/* Alt-Shift: Rotate up */
/* Alt-Ctrl: Rotate right */
/* only work in 3D window for now
* In the end, will have to send to event to a 2D window handler instead
*/
if (Trans.flag & T_2D_EDIT)
return;
switch(event) {
case WHEELUPMOUSE:
if( G.qual & LR_SHIFTKEY ) {
if( G.qual & LR_ALTKEY ) {
G.qual &= ~LR_SHIFTKEY;
persptoetsen(PAD2);
G.qual |= LR_SHIFTKEY;
} else {
persptoetsen(PAD2);
}
} else if( G.qual & LR_CTRLKEY ) {
if( G.qual & LR_ALTKEY ) {
G.qual &= ~LR_CTRLKEY;
persptoetsen(PAD4);
G.qual |= LR_CTRLKEY;
} else {
persptoetsen(PAD4);
}
} else if(U.uiflag & USER_WHEELZOOMDIR)
persptoetsen(PADMINUS);
else
persptoetsen(PADPLUSKEY);
refresh = 1;
break;
case WHEELDOWNMOUSE:
if( G.qual & LR_SHIFTKEY ) {
if( G.qual & LR_ALTKEY ) {
G.qual &= ~LR_SHIFTKEY;
persptoetsen(PAD8);
G.qual |= LR_SHIFTKEY;
} else {
persptoetsen(PAD8);
}
} else if( G.qual & LR_CTRLKEY ) {
if( G.qual & LR_ALTKEY ) {
G.qual &= ~LR_CTRLKEY;
persptoetsen(PAD6);
G.qual |= LR_CTRLKEY;
} else {
persptoetsen(PAD6);
}
} else if(U.uiflag & USER_WHEELZOOMDIR)
persptoetsen(PADPLUSKEY);
else
persptoetsen(PADMINUS);
refresh = 1;
break;
}
if (refresh)
setTransformViewMatrices(&Trans);
}
void checkFirstTime() {
if(Trans.mode==TFM_INIT) {
memset(&Trans, 0, sizeof(TransInfo));
Trans.propsize = 1.0;
}
}
static char *transform_to_undostr(TransInfo *t)
{
switch (t->mode) {
case TFM_TRANSLATION:
return "Translate";
case TFM_ROTATION:
return "Rotate";
case TFM_RESIZE:
return "Scale";
case TFM_TOSPHERE:
return "To Sphere";
case TFM_SHEAR:
return "Shear";
case TFM_WARP:
return "Warp";
case TFM_SHRINKFATTEN:
return "Shrink/Fatten";
case TFM_TILT:
return "Tilt";
case TFM_TRACKBALL:
return "Trackball";
case TFM_PUSHPULL:
return "Push/Pull";
case TFM_BEVEL:
return "Bevel";
case TFM_BWEIGHT:
return "Bevel Weight";
case TFM_CREASE:
return "Crease";
case TFM_BONESIZE:
return "Bone Width";
case TFM_BONE_ENVELOPE:
return "Bone Envelope";
case TFM_TIME_TRANSLATE:
return "Translate Anim. Data";
case TFM_TIME_SCALE:
return "Scale Anim. Data";
case TFM_TIME_SLIDE:
return "Time Slide";
case TFM_BAKE_TIME:
return "Key Time";
case TFM_MIRROR:
return "Mirror";
}
return "Transform";
}
/* ************************************************* */
static void transformEvent(unsigned short event, short val) {
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
float mati[3][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}};
char cmode = constraintModeToChar(&Trans);
if (val) {
switch (event){
/* enforce redraw of transform when modifiers are used */
case LEFTCTRLKEY:
case RIGHTCTRLKEY:
Trans.redraw = 1;
break;
case LEFTSHIFTKEY:
case RIGHTSHIFTKEY:
/* shift is modifier for higher resolution transform, works nice to store this mouse position */
getmouseco_areawin(Trans.shiftmval);
Trans.flag |= T_SHIFT_MOD;
Trans.redraw = 1;
break;
case SPACEKEY:
if ((Trans.spacetype==SPACE_VIEW3D) && (G.qual & LR_ALTKEY)) {
short mval[2];
getmouseco_sc(mval);
BIF_selectOrientation();
calc_manipulator_stats(curarea);
Mat3CpyMat4(Trans.spacemtx, G.vd->twmat);
warp_pointer(mval[0], mval[1]);
}
else {
Trans.state = TRANS_CONFIRM;
}
break;
case MIDDLEMOUSE:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
/* exception for switching to dolly, or trackball, in camera view */
if (Trans.flag & T_CAMERA) {
if (Trans.mode==TFM_TRANSLATION)
setLocalConstraint(&Trans, (CON_AXIS2), "along local Z");
else if (Trans.mode==TFM_ROTATION) {
restoreTransObjects(&Trans);
initTrackball(&Trans);
}
}
else {
Trans.flag |= T_MMB_PRESSED;
if (Trans.con.mode & CON_APPLY) {
stopConstraint(&Trans);
}
else {
if (G.qual & LR_CTRLKEY) {
initSelectConstraint(&Trans, Trans.spacemtx);
}
else {
/* bit hackish... but it prevents mmb select to print the orientation from menu */
strcpy(Trans.spacename, "global");
initSelectConstraint(&Trans, mati);
}
postSelectConstraint(&Trans);
}
}
Trans.redraw = 1;
}
break;
case ESCKEY:
case RIGHTMOUSE:
Trans.state = TRANS_CANCEL;
break;
case LEFTMOUSE:
case PADENTER:
case RETKEY:
Trans.state = TRANS_CONFIRM;
break;
case GKEY:
/* only switch when... */
if( ELEM3(Trans.mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
restoreTransObjects(&Trans);
initTranslation(&Trans);
Trans.redraw = 1;
}
break;
case SKEY:
/* only switch when... */
if( ELEM3(Trans.mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) {
restoreTransObjects(&Trans);
initResize(&Trans);
Trans.redraw = 1;
}
break;
case RKEY:
/* only switch when... */
if( ELEM4(Trans.mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
if (Trans.mode == TFM_ROTATION) {
restoreTransObjects(&Trans);
initTrackball(&Trans);
}
else {
restoreTransObjects(&Trans);
initRotation(&Trans);
}
Trans.redraw = 1;
}
break;
case CKEY:
if (G.qual & LR_ALTKEY) {
Trans.flag ^= T_PROP_CONNECTED;
sort_trans_data_dist(&Trans);
calculatePropRatio(&Trans);
Trans.redraw= 1;
}
else {
stopConstraint(&Trans);
Trans.redraw = 1;
}
break;
case XKEY:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
if (cmode == 'X') {
if (Trans.flag & T_2D_EDIT) {
stopConstraint(&Trans);
}
else {
if (Trans.con.mode & CON_USER) {
stopConstraint(&Trans);
}
else {
if (G.qual == 0)
setUserConstraint(&Trans, (CON_AXIS0), "along %s X");
else if (G.qual == LR_SHIFTKEY)
setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X");
}
}
}
else {
if (Trans.flag & T_2D_EDIT) {
setConstraint(&Trans, mati, (CON_AXIS0), "along X axis");
}
else {
if (G.qual == 0)
setConstraint(&Trans, mati, (CON_AXIS0), "along global X");
else if (G.qual == LR_SHIFTKEY)
setConstraint(&Trans, mati, (CON_AXIS1|CON_AXIS2), "locking global X");
}
}
Trans.redraw = 1;
}
break;
case YKEY:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
if (cmode == 'Y') {
if (Trans.flag & T_2D_EDIT) {
stopConstraint(&Trans);
}
else {
if (Trans.con.mode & CON_USER) {
stopConstraint(&Trans);
}
else {
if (G.qual == 0)
setUserConstraint(&Trans, (CON_AXIS1), "along %s Y");
else if (G.qual == LR_SHIFTKEY)
setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y");
}
}
}
else {
if (Trans.flag & T_2D_EDIT) {
setConstraint(&Trans, mati, (CON_AXIS1), "along Y axis");
}
else {
if (G.qual == 0)
setConstraint(&Trans, mati, (CON_AXIS1), "along global Y");
else if (G.qual == LR_SHIFTKEY)
setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS2), "locking global Y");
}
}
Trans.redraw = 1;
}
break;
case ZKEY:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
if (cmode == 'Z') {
if (Trans.con.mode & CON_USER) {
stopConstraint(&Trans);
}
else {
if (G.qual == 0)
setUserConstraint(&Trans, (CON_AXIS2), "along %s Z");
else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0))
setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS1), "locking %s Z");
}
}
else if ((Trans.flag & T_2D_EDIT)==0) {
if (G.qual == 0)
setConstraint(&Trans, mati, (CON_AXIS2), "along global Z");
else if (G.qual == LR_SHIFTKEY)
setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS1), "locking global Z");
}
Trans.redraw = 1;
}
break;
case OKEY:
if (Trans.flag & T_PROP_EDIT && G.qual==LR_SHIFTKEY) {
G.scene->prop_mode = (G.scene->prop_mode+1)%6;
calculatePropRatio(&Trans);
Trans.redraw= 1;
}
break;
case PADPLUSKEY:
if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 1.1f;
calculatePropRatio(&Trans);
}
Trans.redraw= 1;
break;
case PAGEUPKEY:
case WHEELDOWNMOUSE:
if (Trans.flag & T_AUTOIK) {
transform_autoik_update(&Trans, 1);
}
else if(Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 1.1f;
calculatePropRatio(&Trans);
}
else view_editmove(event);
Trans.redraw= 1;
break;
case PADMINUS:
if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 0.90909090f;
calculatePropRatio(&Trans);
}
Trans.redraw= 1;
break;
case PAGEDOWNKEY:
case WHEELUPMOUSE:
if (Trans.flag & T_AUTOIK) {
transform_autoik_update(&Trans, -1);
}
else if (Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 0.90909090f;
calculatePropRatio(&Trans);
}
else view_editmove(event);
Trans.redraw= 1;
break;
// case NDOFMOTION:
// viewmoveNDOF(1);
// break;
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
// Numerical input events
Trans.redraw |= handleNumInput(&(Trans.num), event);
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
// NDof input events
switch(handleNDofInput(&(Trans.ndof), event, val))
{
case NDOF_CONFIRM:
if ((Trans.context & CTX_NDOF) == 0)
{
/* Confirm on normal transform only */
Trans.state = TRANS_CONFIRM;
}
break;
case NDOF_CANCEL:
if (Trans.context & CTX_NDOF)
{
/* Cancel on pure NDOF transform */
Trans.state = TRANS_CANCEL;
}
else
{
/* Otherwise, just redraw, NDof input was cancelled */
Trans.redraw = 1;
}
break;
case NDOF_NOMOVE:
if (Trans.context & CTX_NDOF)
{
/* Confirm on pure NDOF transform */
Trans.state = TRANS_CONFIRM;
}
break;
case NDOF_REFRESH:
Trans.redraw = 1;
break;
}
// Snapping events
Trans.redraw |= handleSnapping(&Trans, event);
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
arrows_move_cursor(event);
}
else {
switch (event){
/* no redraw on release modifier keys! this makes sure you can assign the 'grid' still
after releasing modifer key */
case MIDDLEMOUSE:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
Trans.flag &= ~T_MMB_PRESSED;
postSelectConstraint(&Trans);
Trans.redraw = 1;
}
break;
case LEFTMOUSE:
case RIGHTMOUSE:
if (Trans.context & CTX_TWEAK)
Trans.state = TRANS_CONFIRM;
break;
case LEFTSHIFTKEY:
case RIGHTSHIFTKEY:
/* shift is modifier for higher resolution transform */
Trans.flag &= ~T_SHIFT_MOD;
break;
}
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
// Per transform event, if present
if (Trans.handleEvent)
Trans.redraw |= Trans.handleEvent(&Trans, event, val);
}
int calculateTransformCenter(int centerMode, float *vec)
{
int success = 1;
checkFirstTime();
Trans.state = TRANS_RUNNING;
Trans.context = CTX_NONE;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
Trans.mode = TFM_DUMMY;
initTrans(&Trans); // internal data, mouse, vectors
createTransData(&Trans); // make TransData structs from selection
Trans.around = centerMode; // override userdefined mode
if (Trans.total == 0) {
success = 0;
}
else {
success = 1;
calculateCenter(&Trans);
// Copy center from constraint center. Transform center can be local
VECCOPY(vec, Trans.con.center);
}
postTrans(&Trans);
/* aftertrans does insert ipos and action channels, and clears base flags, doesnt read transdata */
special_aftertrans_update(&Trans);
return success;
}
void initTransform(int mode, int context) {
/* added initialize, for external calls to set stuff in TransInfo, like undo string */
checkFirstTime();
Trans.state = TRANS_RUNNING;
Trans.context = context;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
Trans.mode = mode;
initTrans(&Trans); // internal data, mouse, vectors
if(Trans.spacetype==SPACE_VIEW3D) {
calc_manipulator_stats(curarea);
Mat3CpyMat4(Trans.spacemtx, G.vd->twmat);
Mat3Ortho(Trans.spacemtx);
}
else
Mat3One(Trans.spacemtx);
createTransData(&Trans); // make TransData structs from selection
initSnapping(&Trans); // Initialize snapping data AFTER mode flags
if (Trans.total == 0) {
postTrans(&Trans);
return;
}
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
/* EVIL2: we gave as argument also texture space context bit... was cleared */
/* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
mode = Trans.mode;
calculatePropRatio(&Trans);
calculateCenter(&Trans);
switch (mode) {
case TFM_TRANSLATION:
initTranslation(&Trans);
break;
case TFM_ROTATION:
initRotation(&Trans);
break;
case TFM_RESIZE:
initResize(&Trans);
break;
case TFM_TOSPHERE:
initToSphere(&Trans);
break;
case TFM_SHEAR:
initShear(&Trans);
break;
case TFM_WARP:
initWarp(&Trans);
break;
case TFM_SHRINKFATTEN:
initShrinkFatten(&Trans);
break;
case TFM_TILT:
initTilt(&Trans);
break;
case TFM_CURVE_SHRINKFATTEN:
initCurveShrinkFatten(&Trans);
break;
case TFM_TRACKBALL:
initTrackball(&Trans);
break;
case TFM_PUSHPULL:
initPushPull(&Trans);
break;
case TFM_CREASE:
initCrease(&Trans);
break;
case TFM_BONESIZE:
{ /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
bArmature *arm= Trans.poseobj->data;
if(arm->drawtype==ARM_ENVELOPE)
initBoneEnvelope(&Trans);
else
initBoneSize(&Trans);
}
break;
case TFM_BONE_ENVELOPE:
initBoneEnvelope(&Trans);
break;
case TFM_BONE_ROLL:
initBoneRoll(&Trans);
break;
case TFM_TIME_TRANSLATE:
initTimeTranslate(&Trans);
break;
case TFM_TIME_SLIDE:
initTimeSlide(&Trans);
break;
case TFM_TIME_SCALE:
initTimeScale(&Trans);
break;
case TFM_TIME_EXTEND:
/* now that transdata has been made, do like for TFM_TIME_TRANSLATE */
initTimeTranslate(&Trans);
break;
case TFM_BAKE_TIME:
initBakeTime(&Trans);
break;
case TFM_MIRROR:
initMirror(&Trans);
break;
case TFM_BEVEL:
initBevel(&Trans);
break;
case TFM_BWEIGHT:
initBevelWeight(&Trans);
break;
case TFM_ALIGN:
initAlign(&Trans);
break;
}
}
void Transform()
{
short pmval[2] = {0, 0}, mval[2], val;
unsigned short event;
if(Trans.total==0) return; // added, can happen now! (ton)
// Emptying event queue
while( qtest() ) {
event= extern_qread(&val);
}
Trans.redraw = 1; /* initial draw */
while (Trans.state == TRANS_RUNNING) {
getmouseco_areawin(mval);
if (mval[0] != pmval[0] || mval[1] != pmval[1]) {
if (Trans.flag & T_MMB_PRESSED)
Trans.con.mode |= CON_SELECT;
Trans.redraw = 1;
}
if (Trans.redraw) {
pmval[0] = mval[0];
pmval[1] = mval[1];
selectConstraint(&Trans);
if (Trans.transform) {
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
Trans.transform(&Trans, mval); // calls recalcData()
}
Trans.redraw = 0;
}
/* If auto confirm is on, break after one pass */
if (Trans.context & CTX_AUTOCONFIRM)
{
Trans.state = TRANS_CONFIRM;
break;
}
/* essential for idling subloop */
if( qtest()==0) PIL_sleep_ms(2);
while( qtest() ) {
event= extern_qread(&val);
transformEvent(event, val);
}
Point Cache Refactoring ======================= Caching and Baking: - The point cache is now cleared on DAG_object_flush_update(), and not cleared for time dependency graph updates. - There is now a Bake button instead of Protect. Also cache start and end frames were added to softbody and particles. - The cloth autoprotect feature was removed. - The Ctrl+B menu now also bakes cloth and particles next to softbody and fluids. Additionally there are now frree bake and free cache menu entries. - The point cache api has been changed. There is now a PTCacheID struct for each point cache type that can be filled and then used to call the point cache functions. - PointCache struct was added to DNA and is automatically allocated for each physics type. - Soft body now supports Bake Editing just like cloth. - Tried to make the systems deal consistently with time ipo's and offsets. Still not sure it all works correct, but too complicated to solve completely now. Library Linking: - Added some more warnings to prevent editing settings on library linked objects. - Linked objects now read from the cache located next to the original library file, and never write to it. This restores old behavior for softbodies. For local simulation the mesh and not the object should be linked. - Dupligroups and proxies can't create local point caches at the moment, how to implement that I'm not sure. We probably need a proxy point cache for that to work (ugh). Physics UI: - Renamed deflection panel to collision for consistency and reorganized the buttons. Also removed some softbody collision buttons from the softbody panel that were duplicated in this panel for cloth. - Tweaked field panel buttons to not jump around when changing options. - Tabbing e.g. Soft Body Collision into the Soft Body panel, it now only shows Collision to make the panel names readable. - I tried to make enabled/disabling physics more consistent, since all three system did things different. Now the two modifier buttons to enable the modifier for the viewport and rendering are also duplicated in the physics panels. Toggling the Soft Body and Cloth buttons now both remove their modifiers. - Fixed modifier error drawing glitch. Particles: - Particles are now recalculated more often than before. Previously it did partial updates based on the changes, but that doesn't work well with DAG_object_flush_update() .. - Fixed memory leak loading keyed particle system. Now keys are not written to file anymore but always created after loading. - Make particle threads work with autothreads. Continue Physics: - The timeline play now has a Continue Physics option in the playback menu, which keeps the simulations going without writing them to the cache. - This doesn't always work that well, some changes are not immediately updated, but this can be improved later. Still it's fun to get a feel for the physics. Todo: - Point cache can get out of sync with and undo and changing a file without saving it. - Change the point cache file format to store a version (so old point cache files can be either converted or at least ignored), and to do correct endian conversion. - Menu item and/or buttons for Ctrl+B. - A system("rm ..") was changed to remove() since the former is very slow for clearing point caches. These system() calls were already giving trouble in a bug in the tracker, but really most use of this system("") should be changed and tested. - The Soft Body Collision and Clot Collision panel titles don't mention there's point cache settings there too, doing that makes them unreadable with the default panel setup.. but may need to make the names longer anyway.
2008-04-10 11:39:20 +00:00
if(BKE_ptcache_get_continue_physics()) {
do_screenhandlers(G.curscreen);
Trans.redraw= 1;
}
}
/* handle restoring objects */
if(Trans.state == TRANS_CANCEL)
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
restoreTransObjects(&Trans); // calls recalcData()
/* free data */
postTrans(&Trans);
/* aftertrans does insert ipos and action channels, and clears base flags, doesnt read transdata */
special_aftertrans_update(&Trans);
/* send events out for redraws */
viewRedrawPost(&Trans);
/* Undo as last, certainly after special_trans_update! */
if(Trans.state == TRANS_CANCEL) {
if(Trans.undostr) BIF_undo_push(Trans.undostr);
}
else {
if(Trans.undostr) BIF_undo_push(Trans.undostr);
else BIF_undo_push(transform_to_undostr(&Trans));
}
Trans.undostr= NULL;
}
/* ************************** Manipulator init and main **************************** */
void initManipulator(int mode)
{
Trans.state = TRANS_RUNNING;
Trans.context = CTX_NONE;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
Trans.mode = mode;
/* automatic switch to scaling bone envelopes */
if(mode==TFM_RESIZE && G.obedit && G.obedit->type==OB_ARMATURE) {
bArmature *arm= G.obedit->data;
if(arm->drawtype==ARM_ENVELOPE)
mode= TFM_BONE_ENVELOPE;
}
initTrans(&Trans); // internal data, mouse, vectors
G.moving |= G_TRANSFORM_MANIP; // signal to draw manipuls while transform
createTransData(&Trans); // make TransData structs from selection
if (Trans.total == 0)
return;
initSnapping(&Trans); // Initialize snapping data AFTER mode flags
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
/* EVIL2: we gave as argument also texture space context bit... was cleared */
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
mode = Trans.mode;
calculatePropRatio(&Trans);
calculateCenter(&Trans);
switch (mode) {
case TFM_TRANSLATION:
initTranslation(&Trans);
break;
case TFM_ROTATION:
initRotation(&Trans);
break;
case TFM_RESIZE:
initResize(&Trans);
break;
case TFM_TRACKBALL:
initTrackball(&Trans);
break;
}
Trans.flag |= T_USES_MANIPULATOR;
}
void ManipulatorTransform()
{
int mouse_moved = 0;
short pmval[2] = {0, 0}, mval[2], val;
unsigned short event;
if (Trans.total == 0)
return;
Trans.redraw = 1; /* initial draw */
while (Trans.state == TRANS_RUNNING) {
getmouseco_areawin(mval);
if (mval[0] != pmval[0] || mval[1] != pmval[1]) {
Trans.redraw = 1;
}
if (Trans.redraw) {
pmval[0] = mval[0];
pmval[1] = mval[1];
//selectConstraint(&Trans); needed?
if (Trans.transform) {
Trans.transform(&Trans, mval);
}
Trans.redraw = 0;
}
/* essential for idling subloop */
if( qtest()==0) PIL_sleep_ms(2);
while( qtest() ) {
event= extern_qread(&val);
switch (event){
case MOUSEX:
case MOUSEY:
mouse_moved = 1;
break;
/* enforce redraw of transform when modifiers are used */
case LEFTCTRLKEY:
case RIGHTCTRLKEY:
if(val) Trans.redraw = 1;
break;
case LEFTSHIFTKEY:
case RIGHTSHIFTKEY:
/* shift is modifier for higher resolution transform, works nice to store this mouse position */
if(val) {
getmouseco_areawin(Trans.shiftmval);
Trans.flag |= T_SHIFT_MOD;
Trans.redraw = 1;
}
else Trans.flag &= ~T_SHIFT_MOD;
break;
case ESCKEY:
case RIGHTMOUSE:
Trans.state = TRANS_CANCEL;
break;
case LEFTMOUSE:
if(mouse_moved==0 && val==0) break;
// else we pass on event to next, which cancels
case SPACEKEY:
case PADENTER:
case RETKEY:
Trans.state = TRANS_CONFIRM;
break;
// case NDOFMOTION:
// viewmoveNDOF(1);
// break;
}
if(val) {
switch(event) {
case PADPLUSKEY:
if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 1.1f;
calculatePropRatio(&Trans);
}
Trans.redraw= 1;
break;
case PAGEUPKEY:
case WHEELDOWNMOUSE:
if (Trans.flag & T_AUTOIK) {
transform_autoik_update(&Trans, 1);
}
else if(Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 1.1f;
calculatePropRatio(&Trans);
}
else view_editmove(event);
Trans.redraw= 1;
break;
case PADMINUS:
if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 0.90909090f;
calculatePropRatio(&Trans);
}
Trans.redraw= 1;
break;
case PAGEDOWNKEY:
case WHEELUPMOUSE:
if (Trans.flag & T_AUTOIK) {
transform_autoik_update(&Trans, -1);
}
else if (Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 0.90909090f;
calculatePropRatio(&Trans);
}
else view_editmove(event);
Trans.redraw= 1;
break;
}
// Numerical input events
Trans.redraw |= handleNumInput(&(Trans.num), event);
}
}
}
if(Trans.state == TRANS_CANCEL) {
restoreTransObjects(&Trans);
}
/* free data, reset vars */
postTrans(&Trans);
/* aftertrans does insert ipos and action channels, and clears base flags */
special_aftertrans_update(&Trans);
/* send events out for redraws */
viewRedrawPost(&Trans);
if(Trans.state != TRANS_CANCEL) {
BIF_undo_push(transform_to_undostr(&Trans));
}
}
/* ************************** TRANSFORM LOCKS **************************** */
static void protectedTransBits(short protectflag, float *vec)
{
if(protectflag & OB_LOCK_LOCX)
vec[0]= 0.0f;
if(protectflag & OB_LOCK_LOCY)
vec[1]= 0.0f;
if(protectflag & OB_LOCK_LOCZ)
vec[2]= 0.0f;
}
static void protectedSizeBits(short protectflag, float *size)
{
if(protectflag & OB_LOCK_SCALEX)
size[0]= 1.0f;
if(protectflag & OB_LOCK_SCALEY)
size[1]= 1.0f;
if(protectflag & OB_LOCK_SCALEZ)
size[2]= 1.0f;
}
static void protectedRotateBits(short protectflag, float *eul, float *oldeul)
{
if(protectflag & OB_LOCK_ROTX)
eul[0]= oldeul[0];
if(protectflag & OB_LOCK_ROTY)
eul[1]= oldeul[1];
if(protectflag & OB_LOCK_ROTZ)
eul[2]= oldeul[2];
}
static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat)
{
/* quaternions get limited with euler... */
/* this function only does the delta rotation */
if(protectflag) {
float eul[3], oldeul[3], quat1[4];
QUATCOPY(quat1, quat);
QuatToEul(quat, eul);
QuatToEul(oldquat, oldeul);
if(protectflag & OB_LOCK_ROTX)
eul[0]= oldeul[0];
if(protectflag & OB_LOCK_ROTY)
eul[1]= oldeul[1];
if(protectflag & OB_LOCK_ROTZ)
eul[2]= oldeul[2];
EulToQuat(eul, quat);
/* quaternions flip w sign to accumulate rotations correctly */
if( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) {
QuatMulf(quat, -1.0f);
}
}
}
/* ******************* TRANSFORM LIMITS ********************** */
static void constraintTransLim(TransInfo *t, TransData *td)
{
if (td->con) {
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
bConstraintOb cob;
bConstraint *con;
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
Mat4One(cob.matrix);
if (td->tdi) {
TransDataIpokey *tdi= td->tdi;
cob.matrix[3][0]= tdi->locx[0];
cob.matrix[3][1]= tdi->locy[0];
cob.matrix[3][2]= tdi->locz[0];
}
else {
VECCOPY(cob.matrix[3], td->loc);
}
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
float tmat[4][4];
/* only use it if it's tagged for this purpose (and the right type) */
if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
bLocLimitConstraint *data= con->data;
if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue;
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
Mat4CpyMat4(tmat, cob.matrix);
Mat4MulMat34(cob.matrix, td->mtx, tmat);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* skip... incompatable spacetype */
continue;
}
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
Mat4CpyMat4(tmat, cob.matrix);
Mat4MulMat34(cob.matrix, td->smtx, tmat);
}
}
}
/* copy results from cob->matrix */
if (td->tdi) {
TransDataIpokey *tdi= td->tdi;
tdi->locx[0]= cob.matrix[3][0];
tdi->locy[0]= cob.matrix[3][1];
tdi->locz[0]= cob.matrix[3][2];
}
else {
VECCOPY(td->loc, cob.matrix[3]);
}
}
}
static void constraintRotLim(TransInfo *t, TransData *td)
{
if (td->con) {
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
bConstraintOb cob;
bConstraint *con;
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
if (td->flag & TD_USEQUAT) {
/* quats */
if (td->ext)
QuatToMat4(td->ext->quat, cob.matrix);
else
return;
}
else if (td->tdi) {
/* ipo-keys eulers */
TransDataIpokey *tdi= td->tdi;
float eul[3];
eul[0]= tdi->rotx[0];
eul[1]= tdi->roty[0];
eul[2]= tdi->rotz[0];
EulToMat4(eul, cob.matrix);
}
else {
/* eulers */
if (td->ext)
EulToMat4(td->ext->rot, cob.matrix);
else
return;
}
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
/* we're only interested in Limit-Scale constraints */
if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
bRotLimitConstraint *data= con->data;
float tmat[4][4];
/* only use it if it's tagged for this purpose */
if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue;
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
Mat4CpyMat4(tmat, cob.matrix);
Mat4MulMat34(cob.matrix, td->mtx, tmat);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* skip... incompatable spacetype */
continue;
}
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
Mat4CpyMat4(tmat, cob.matrix);
Mat4MulMat34(cob.matrix, td->smtx, tmat);
}
}
}
/* copy results from cob->matrix */
if (td->flag & TD_USEQUAT) {
/* quats */
Mat4ToQuat(cob.matrix, td->ext->quat);
}
else if (td->tdi) {
/* ipo-keys eulers */
TransDataIpokey *tdi= td->tdi;
float eul[3];
Mat4ToEul(cob.matrix, eul);
tdi->rotx[0]= eul[0];
tdi->roty[0]= eul[1];
tdi->rotz[0]= eul[2];
}
else {
/* eulers */
Mat4ToEul(cob.matrix, td->ext->rot);
}
}
}
static void constraintSizeLim(TransInfo *t, TransData *td)
{
if (td->con && td->ext) {
bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT);
bConstraintOb cob;
bConstraint *con;
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
* - current space should be local
*/
memset(&cob, 0, sizeof(bConstraintOb));
if (td->tdi) {
TransDataIpokey *tdi= td->tdi;
float size[3];
size[0]= tdi->sizex[0];
size[1]= tdi->sizey[0];
size[2]= tdi->sizez[0];
SizeToMat4(size, cob.matrix);
}
else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
/* scale val and reset size */
return; // TODO: fix this case
}
else {
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
SizeToMat4(td->ext->size, cob.matrix);
}
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
/* we're only interested in Limit-Scale constraints */
if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
bSizeLimitConstraint *data= con->data;
float tmat[4][4];
/* only use it if it's tagged for this purpose */
if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue;
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
Mat4CpyMat4(tmat, cob.matrix);
Mat4MulMat34(cob.matrix, td->mtx, tmat);
}
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
/* skip... incompatable spacetype */
continue;
}
/* do constraint */
cti->evaluate_constraint(con, &cob, NULL);
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
Mat4CpyMat4(tmat, cob.matrix);
Mat4MulMat34(cob.matrix, td->smtx, tmat);
}
}
}
/* copy results from cob->matrix */
if (td->tdi) {
TransDataIpokey *tdi= td->tdi;
float size[3];
Mat4ToSize(cob.matrix, size);
tdi->sizex[0]= size[0];
tdi->sizey[0]= size[1];
tdi->sizez[0]= size[2];
}
else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
/* scale val and reset size */
return; // TODO: fix this case
}
else {
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
return;
Mat4ToSize(cob.matrix, td->ext->size);
}
}
}
/* ************************** WARP *************************** */
void initWarp(TransInfo *t)
{
float max[3], min[3];
int i;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_WARP;
t->transform = Warp;
t->handleEvent = handleEventWarp;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 5.0f;
t->snap[2] = 1.0f;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
/* warp is done fully in view space */
calculateCenterCursor(t);
t->fac = (float)(t->center2d[0] - t->imval[0]);
/* we need min/max in view space */
for(i = 0; i < t->total; i++) {
float center[3];
VECCOPY(center, t->data[i].center);
Mat3MulVecfl(t->data[i].mtx, center);
Mat4MulVecfl(t->viewmat, center);
VecSubf(center, center, t->viewmat[3]);
if (i)
MinMax3(min, max, center);
else {
VECCOPY(max, center);
VECCOPY(min, center);
}
}
t->center[0]= (min[0]+max[0])/2.0f;
t->center[1]= (min[1]+max[1])/2.0f;
t->center[2]= (min[2]+max[2])/2.0f;
if (max[0] == min[0]) max[0] += 0.1; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */
t->val= (max[0]-min[0])/2.0f; /* t->val is X dimension projected boundbox */
}
int handleEventWarp(TransInfo *t, unsigned short event, short val)
{
int status = 0;
if (event == MIDDLEMOUSE && val)
{
// Use customData pointer to signal warp direction
if (t->customData == 0)
t->customData = (void*)1;
else
t->customData = 0;
status = 1;
}
return status;
}
int Warp(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3];
int i;
char str[50];
curs= give_cursor();
/*
* gcursor is the one used for helpline.
* It has to be in the same space as the drawing loop
* (that means it needs to be in the object's space when in edit mode and
* in global space in object mode)
*
* cursor is used for calculations.
* It needs to be in view space, but we need to take object's offset
* into account if in Edit mode.
*/
VECCOPY(cursor, curs);
VECCOPY(gcursor, cursor);
if (t->flag & T_EDIT) {
VecSubf(cursor, cursor, G.obedit->obmat[3]);
VecSubf(gcursor, gcursor, G.obedit->obmat[3]);
Mat3MulVecfl(t->data->smtx, gcursor);
}
Mat4MulVecfl(t->viewmat, cursor);
VecSubf(cursor, cursor, t->viewmat[3]);
/* amount of degrees for warp */
circumfac= 360.0f * InputHorizontalRatio(t, mval);
if (t->customData) /* non-null value indicates reversed input */
{
circumfac *= -1;
}
snapGrid(t, &circumfac);
applyNumInput(&t->num, &circumfac);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "Warp: %s", c);
}
else {
/* default header print */
sprintf(str, "Warp: %.3f", circumfac);
}
circumfac*= (float)(-M_PI/360.0);
for(i = 0; i < t->total; i++, td++) {
float loc[3];
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
/* translate point to center, rotate in such a way that outline==distance */
VECCOPY(vec, td->iloc);
Mat3MulVecfl(td->mtx, vec);
Mat4MulVecfl(t->viewmat, vec);
VecSubf(vec, vec, t->viewmat[3]);
dist= vec[0]-cursor[0];
/* t->val is X dimension projected boundbox */
phi0= (circumfac*dist/t->val);
vec[1]= (vec[1]-cursor[1]);
co= (float)cos(phi0);
si= (float)sin(phi0);
loc[0]= -si*vec[1]+cursor[0];
loc[1]= co*vec[1]+cursor[1];
loc[2]= vec[2];
Mat4MulVecfl(t->viewinv, loc);
VecSubf(loc, loc, t->viewinv[3]);
Mat3MulVecfl(td->smtx, loc);
VecSubf(loc, loc, td->iloc);
VecMulf(loc, td->factor);
VecAddf(td->loc, td->iloc, loc);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
helpline(t, gcursor);
return 1;
}
/* ************************** SHEAR *************************** */
void initShear(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_SHEAR;
t->transform = Shear;
t->handleEvent = handleEventShear;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
int handleEventShear(TransInfo *t, unsigned short event, short val)
{
int status = 0;
if (event == MIDDLEMOUSE && val)
{
// Use customData pointer to signal Shear direction
if (t->customData == 0)
t->customData = (void*)1;
else
t->customData = 0;
status = 1;
}
return status;
}
int Shear(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float vec[3];
float smat[3][3], tmat[3][3], totmat[3][3], persmat[3][3], persinv[3][3];
float value;
int i;
char str[50];
Mat3CpyMat4(persmat, t->viewmat);
Mat3Inv(persinv, persmat);
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
// Custom data signals shear direction
if (t->customData == 0)
value = 0.05f * InputHorizontalAbsolute(t, mval);
else
value = 0.05f * InputVerticalAbsolute(t, mval);
snapGrid(t, &value);
applyNumInput(&t->num, &value);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "Shear: %s %s", c, t->proptext);
}
else {
/* default header print */
sprintf(str, "Shear: %.3f %s", value, t->proptext);
}
Mat3One(smat);
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
// Custom data signals shear direction
if (t->customData == 0)
smat[1][0] = value;
else
smat[0][1] = value;
Mat3MulMat3(tmat, smat, persmat);
Mat3MulMat3(totmat, persinv, tmat);
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (G.obedit) {
float mat3[3][3];
Mat3MulMat3(mat3, totmat, td->mtx);
Mat3MulMat3(tmat, td->smtx, mat3);
}
else {
Mat3CpyMat3(tmat, totmat);
}
VecSubf(vec, td->center, t->center);
Mat3MulVecfl(tmat, vec);
VecAddf(vec, vec, t->center);
VecSubf(vec, vec, td->center);
VecMulf(vec, td->factor);
VecAddf(td->loc, td->iloc, vec);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
helpline (t, t->center);
return 1;
}
/* ************************** RESIZE *************************** */
void initResize(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_RESIZE;
t->transform = Resize;
t->flag |= T_NULL_ONE;
t->num.flag |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
if (!G.obedit) {
t->flag |= T_NO_ZERO;
t->num.flag |= NUM_NO_ZERO;
}
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
t->fac = (float)sqrt(
(
((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+
((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
) );
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
2005-03-14 20:10:22 +00:00
static void headerResize(TransInfo *t, float vec[3], char *str) {
char tvec[60];
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
else {
sprintf(&tvec[0], "%.4f", vec[0]);
sprintf(&tvec[20], "%.4f", vec[1]);
sprintf(&tvec[40], "%.4f", vec[2]);
}
if (t->con.mode & CON_APPLY) {
switch(t->num.idx_max) {
case 0:
sprintf(str, "Scale: %s%s %s", &tvec[0], t->con.text, t->proptext);
break;
case 1:
sprintf(str, "Scale: %s : %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext);
break;
case 2:
sprintf(str, "Scale: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
}
}
else {
if (t->flag & T_2D_EDIT)
sprintf(str, "Scale X: %s Y: %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext);
else
sprintf(str, "Scale X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
}
}
#define SIGN(a) (a<-FLT_EPSILON?1:a>FLT_EPSILON?2:3)
#define VECSIGNFLIP(a, b) ((SIGN(a[0]) & SIGN(b[0]))==0 || (SIGN(a[1]) & SIGN(b[1]))==0 || (SIGN(a[2]) & SIGN(b[2]))==0)
/* smat is reference matrix, only scaled */
static void TransMat3ToSize( float mat[][3], float smat[][3], float *size)
{
float vec[3];
VecCopyf(vec, mat[0]);
size[0]= Normalize(vec);
VecCopyf(vec, mat[1]);
size[1]= Normalize(vec);
VecCopyf(vec, mat[2]);
size[2]= Normalize(vec);
/* first tried with dotproduct... but the sign flip is crucial */
if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0];
if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1];
if( VECSIGNFLIP(mat[2], smat[2]) ) size[2]= -size[2];
}
static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
float tmat[3][3], smat[3][3], center[3];
float vec[3];
if (t->flag & T_EDIT) {
Mat3MulMat3(smat, mat, td->mtx);
Mat3MulMat3(tmat, td->smtx, smat);
}
else {
Mat3CpyMat3(tmat, mat);
}
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
}
/* local constraint shouldn't alter center */
if (t->around == V3D_LOCAL) {
if (t->flag & T_OBJECT) {
VECCOPY(center, td->center);
}
else if (t->flag & T_EDIT) {
if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) {
VECCOPY(center, td->center);
}
else {
VECCOPY(center, t->center);
}
}
else {
VECCOPY(center, t->center);
}
}
else {
VECCOPY(center, t->center);
}
if (td->ext) {
float fsize[3];
if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) {
float obsizemat[3][3];
// Reorient the size mat to fit the oriented object.
Mat3MulMat3(obsizemat, tmat, td->axismtx);
//printmatrix3("obsizemat", obsizemat);
TransMat3ToSize(obsizemat, td->axismtx, fsize);
//printvecf("fsize", fsize);
}
else {
Mat3ToSize(tmat, fsize);
}
protectedSizeBits(td->protectflag, fsize);
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't resize objects itself
/* handle ipokeys? */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
/* calculate delta size (equal for size and dsize) */
vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor;
vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor;
vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor;
add_tdi_poin(tdi->sizex, tdi->oldsize, vec[0]);
add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]);
add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]);
}
else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
/* scale val and reset size */
*td->val = td->ival * fsize[0] * td->factor;
td->ext->size[0] = td->ext->isize[0];
td->ext->size[1] = td->ext->isize[1];
td->ext->size[2] = td->ext->isize[2];
}
else {
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
*td->val = td->ival;
td->ext->size[0] = td->ext->isize[0] * (fsize[0]) * td->factor;
td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor;
td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor;
}
}
constraintSizeLim(t, td);
}
/* For individual element center, Editmode need to use iloc */
if (t->flag & T_POINTS)
VecSubf(vec, td->iloc, center);
else
VecSubf(vec, td->center, center);
Mat3MulVecfl(tmat, vec);
VecAddf(vec, vec, center);
if (t->flag & T_POINTS)
VecSubf(vec, vec, td->iloc);
else
VecSubf(vec, vec, td->center);
VecMulf(vec, td->factor);
if (t->flag & (T_OBJECT|T_POSE)) {
Mat3MulVecfl(td->smtx, vec);
}
protectedTransBits(td->protectflag, vec);
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
}
else VecAddf(td->loc, td->iloc, vec);
constraintTransLim(t, td);
}
int Resize(TransInfo *t, short mval[2])
{
TransData *td;
float size[3], mat[3][3];
float ratio;
int i;
char str[200];
/* for manipulator, center handle, the scaling can't be done relative to center */
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) {
ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1]))/100.0f;
}
else {
ratio = InputScaleRatio(t, mval);
/* flip scale, but not for manipulator center handle */
if ((t->center2d[0] - mval[0]) * (t->center2d[0] - t->imval[0]) +
(t->center2d[1] - mval[1]) * (t->center2d[1] - t->imval[1]) < 0)
ratio *= -1.0f;
}
size[0] = size[1] = size[2] = ratio;
snapGrid(t, size);
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, size);
constraintNumInput(t, size);
}
applySnapping(t, size);
SizeToMat3(size, mat);
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
Mat3CpyMat3(t->mat, mat); // used in manipulator
headerResize(t, size, str);
for(i = 0, td=t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
ElementResize(t, td, mat);
}
/* evil hack - redo resize if cliping needed */
if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) {
SizeToMat3(size, mat);
if (t->con.applySize)
t->con.applySize(t, NULL, mat);
for(i = 0, td=t->data; i < t->total; i++, td++)
ElementResize(t, td, mat);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
return 1;
}
/* ************************** TOSPHERE *************************** */
void initToSphere(TransInfo *t)
{
TransData *td = t->data;
int i;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_TOSPHERE;
t->transform = ToSphere;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
// Calculate average radius
for(i = 0 ; i < t->total; i++, td++) {
t->val += VecLenf(t->center, td->iloc);
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->val /= (float)t->total;
}
int ToSphere(TransInfo *t, short mval[2])
{
float vec[3];
float ratio, radius;
int i;
char str[64];
TransData *td = t->data;
ratio = InputHorizontalRatio(t, mval);
snapGrid(t, &ratio);
applyNumInput(&t->num, &ratio);
if (ratio < 0)
ratio = 0.0f;
else if (ratio > 1)
ratio = 1.0f;
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "To Sphere: %s %s", c, t->proptext);
}
else {
/* default header print */
sprintf(str, "To Sphere: %.4f %s", ratio, t->proptext);
}
for(i = 0 ; i < t->total; i++, td++) {
float tratio;
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
VecSubf(vec, td->iloc, t->center);
radius = Normalize(vec);
tratio = ratio * td->factor;
VecMulf(vec, radius * (1.0f - tratio) + t->val * tratio);
VecAddf(td->loc, t->center, vec);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
return 1;
}
/* ************************** ROTATION *************************** */
void initRotation(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_ROTATION;
t->transform = Rotation;
t->ndof.axis = 16;
/* Scale down and flip input for rotation */
t->ndof.factor[0] = -0.2f;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
t->fac = 0;
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
}
static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around) {
float vec[3], totmat[3][3], smat[3][3];
float eul[3], fmat[3][3], quat[4];
float *center = t->center;
/* local constraint shouldn't alter center */
if (around == V3D_LOCAL) {
if (t->flag & (T_OBJECT|T_POSE)) {
center = td->center;
}
else {
/* !TODO! Make this if not rely on G */
if(around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) {
center = td->center;
}
}
}
if (t->flag & T_POINTS) {
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat);
VecSubf(vec, td->iloc, center);
Mat3MulVecfl(smat, vec);
VecAddf(td->loc, vec, center);
VecSubf(vec,td->loc,td->iloc);
protectedTransBits(td->protectflag, vec);
VecAddf(td->loc, td->iloc, vec);
if(td->flag & TD_USEQUAT) {
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
if(td->ext->quat){
QuatMul(td->ext->quat, quat, td->ext->iquat);
/* is there a reason not to have this here? -jahka */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
}
}
/**
* HACK WARNING
*
* This is some VERY ugly special case to deal with pose mode.
*
* The problem is that mtx and smtx include each bone orientation.
*
* That is needed to rotate each bone properly, HOWEVER, to calculate
* the translation component, we only need the actual armature object's
* matrix (and inverse). That is not all though. Once the proper translation
* has been computed, it has to be converted back into the bone's space.
*/
else if (t->flag & T_POSE) {
float pmtx[3][3], imtx[3][3];
// Extract and invert armature object matrix
Mat3CpyMat4(pmtx, t->poseobj->obmat);
Mat3Inv(imtx, pmtx);
VecSubf(vec, td->center, center);
Mat3MulVecfl(pmtx, vec); // To Global space
Mat3MulVecfl(mat, vec); // Applying rotation
Mat3MulVecfl(imtx, vec); // To Local space
VecAddf(vec, vec, center);
/* vec now is the location where the object has to be */
VecSubf(vec, vec, td->center); // Translation needed from the initial location
Mat3MulVecfl(pmtx, vec); // To Global space
Mat3MulVecfl(td->smtx, vec);// To Pose space
protectedTransBits(td->protectflag, vec);
VecAddf(td->loc, td->iloc, vec);
constraintTransLim(t, td);
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
QuatMul(td->ext->quat, quat, td->ext->iquat);
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
constraintRotLim(t, td);
}
}
else {
/* translation */
VecSubf(vec, td->center, center);
Mat3MulVecfl(mat, vec);
VecAddf(vec, vec, center);
/* vec now is the location where the object has to be */
VecSubf(vec, vec, td->center);
Mat3MulVecfl(td->smtx, vec);
protectedTransBits(td->protectflag, vec);
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
}
else VecAddf(td->loc, td->iloc, vec);
constraintTransLim(t, td);
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
if(td->flag & TD_USEQUAT) {
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
QuatMul(td->ext->quat, quat, td->ext->iquat);
/* this function works on end result */
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
}
else {
float obmat[3][3];
/* are there ipo keys? */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
float current_rot[3];
float rot[3];
/* current IPO value for compatible euler */
current_rot[0] = tdi->rotx[0];
current_rot[1] = tdi->roty[0];
current_rot[2] = tdi->rotz[0];
VecMulf(current_rot, (float)(M_PI_2 / 9.0));
/* calculate the total rotatation in eulers */
VecAddf(eul, td->ext->irot, td->ext->drot);
EulToMat3(eul, obmat);
/* mat = transform, obmat = object rotation */
Mat3MulMat3(fmat, mat, obmat);
Mat3ToCompatibleEul(fmat, eul, current_rot);
/* correct back for delta rot */
if(tdi->flag & TOB_IPODROT) {
VecSubf(rot, eul, td->ext->irot);
}
else {
VecSubf(rot, eul, td->ext->drot);
}
VecMulf(rot, (float)(9.0/M_PI_2));
VecSubf(rot, rot, tdi->oldrot);
protectedRotateBits(td->protectflag, rot, tdi->oldrot);
add_tdi_poin(tdi->rotx, tdi->oldrot, rot[0]);
add_tdi_poin(tdi->roty, tdi->oldrot+1, rot[1]);
add_tdi_poin(tdi->rotz, tdi->oldrot+2, rot[2]);
}
else {
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat);
/* calculate the total rotatation in eulers */
VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
EulToMat3(eul, obmat);
/* mat = transform, obmat = object rotation */
Mat3MulMat3(fmat, smat, obmat);
Mat3ToCompatibleEul(fmat, eul, td->ext->rot);
/* correct back for delta rot */
VecSubf(eul, eul, td->ext->drot);
/* and apply */
protectedRotateBits(td->protectflag, eul, td->ext->irot);
VECCOPY(td->ext->rot, eul);
}
}
constraintRotLim(t, td);
}
}
}
static void applyRotation(TransInfo *t, float angle, float axis[3])
{
TransData *td = t->data;
float mat[3][3];
int i;
VecRotToMat3(axis, angle, mat);
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (t->con.applyRot) {
t->con.applyRot(t, td, axis, NULL);
VecRotToMat3(axis, angle * td->factor, mat);
}
else if (t->flag & T_PROP_EDIT) {
VecRotToMat3(axis, angle * td->factor, mat);
}
ElementRotation(t, td, mat, t->around);
}
}
int Rotation(TransInfo *t, short mval[2])
{
char str[64];
float final;
float axis[3];
float mat[3][3];
VECCOPY(axis, t->viewinv[2]);
VecMulf(axis, -1.0f);
Normalize(axis);
t->fac += InputDeltaAngle(t, mval);
final = t->fac;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
applyNDofInput(&t->ndof, &final);
snapGrid(t, &final);
if (t->con.applyRot) {
t->con.applyRot(t, NULL, axis, &final);
}
applySnapping(t, &final);
if (hasNumInput(&t->num)) {
char c[20];
applyNumInput(&t->num, &final);
outputNumInput(&(t->num), c);
=== Custom Transform Orientation === Custom Orientations can be added with Ctrl-Shift-C (hotkey suggestions are welcomed), this adds and select the new alignment. Custom Orientations can also be added, deleted, selected from the Transform Orientations panel (View -> Transform Orientations). Standard orientations (global, local, normal, view) can also be selected from this panel. If you plan on using only a single custom orientation and don't really need a list, I suggest you use the hotkey as it adds and selects at the same time. Custom Orientations are save in the scene and are selected per 3D view (like normal orientation). Adding from an object, the orientation is a normalized version of the object's orientation. Adding from mesh data, a single element (vertex, edge, face) must be selected in its respective selection mode. Vertex orientation Z-axis is based on the normal, edge Z-axis on the edge itself (X-axis is on the XoY plane when possible, Y-axis is perpendicular to the rest). Face orientation Z-axis is the face normal, X-axis is perpendicular to the first edge, Y-axis is perpendicular to the rest. (More logical orientations can be suggested). I plan to add: 2 vertice (connected or not) => edge orientation , 3 vertice = face orientation Differences from the patch: - orientations no longer link back to the object they came from, everything is copy on creation. - orientations are overwritten based on name (if you add an orientation with the same name as one that already exists, it overwrites the old one)
2008-01-13 18:24:09 +00:00
sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext);
/* Clamp between -180 and 180 */
while (final >= 180.0)
final -= 360.0;
while (final <= -180.0)
final += 360.0;
final *= (float)(M_PI / 180.0);
}
else {
sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext);
}
VecRotToMat3(axis, final, mat);
t->val = final; // used in manipulator
Mat3CpyMat3(t->mat, mat); // used in manipulator
applyRotation(t, final, axis);
recalcData(t);
headerprint(str);
viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
return 1;
}
/* ************************** TRACKBALL *************************** */
void initTrackball(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_TRACKBALL;
t->transform = Trackball;
t->ndof.axis = 40;
/* Scale down input for rotation */
t->ndof.factor[0] = 0.2f;
t->ndof.factor[1] = 0.2f;
t->idx_max = 1;
t->num.idx_max = 1;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
t->fac = 0;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
}
static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float angles[2])
{
TransData *td = t->data;
float mat[3][3], smat[3][3], totmat[3][3];
int i;
VecRotToMat3(axis1, angles[0], smat);
VecRotToMat3(axis2, angles[1], totmat);
Mat3MulMat3(mat, smat, totmat);
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (t->flag & T_PROP_EDIT) {
VecRotToMat3(axis1, td->factor * angles[0], smat);
VecRotToMat3(axis2, td->factor * angles[1], totmat);
Mat3MulMat3(mat, smat, totmat);
}
ElementRotation(t, td, mat, t->around);
}
}
int Trackball(TransInfo *t, short mval[2])
{
char str[128];
float axis1[3], axis2[3];
float mat[3][3], totmat[3][3], smat[3][3];
float phi[2];
VECCOPY(axis1, t->persinv[0]);
VECCOPY(axis2, t->persinv[1]);
Normalize(axis1);
Normalize(axis2);
/* factore has to become setting or so */
phi[0]= 0.01f*(float)( t->imval[1] - mval[1] );
phi[1]= 0.01f*(float)( mval[0] - t->imval[0] );
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
applyNDofInput(&t->ndof, phi);
snapGrid(t, phi);
if (hasNumInput(&t->num)) {
char c[40];
applyNumInput(&t->num, phi);
outputNumInput(&(t->num), c);
sprintf(str, "Trackball: %s %s %s", &c[0], &c[20], t->proptext);
phi[0] *= (float)(M_PI / 180.0);
phi[1] *= (float)(M_PI / 180.0);
}
else {
sprintf(str, "Trackball: %.2f %.2f %s", 180.0*phi[0]/M_PI, 180.0*phi[1]/M_PI, t->proptext);
if(t->flag & T_SHIFT_MOD) {
if(phi[0] != 0.0) phi[0]/= 5.0f;
if(phi[1] != 0.0) phi[1]/= 5.0f;
}
}
VecRotToMat3(axis1, phi[0], smat);
VecRotToMat3(axis2, phi[1], totmat);
Mat3MulMat3(mat, smat, totmat);
Mat3CpyMat3(t->mat, mat); // used in manipulator
applyTrackball(t, axis1, axis2, phi);
recalcData(t);
headerprint(str);
viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
return 1;
}
/* ************************** TRANSLATION *************************** */
void initTranslation(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_TRANSLATION;
t->transform = Translation;
t->idx_max = (t->flag & T_2D_EDIT)? 1: 2;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->num.flag = 0;
t->num.idx_max = t->idx_max;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->ndof.axis = 7;
if(t->spacetype == SPACE_VIEW3D) {
/* initgrabz() defines a factor for perspective depth correction, used in window_to_3d() */
if(t->flag & (T_EDIT|T_POSE)) {
Object *ob= G.obedit?G.obedit:t->poseobj;
float vec[3];
VECCOPY(vec, t->center);
Mat4MulVecfl(ob->obmat, vec);
initgrabz(vec[0], vec[1], vec[2]);
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
else {
initgrabz(t->center[0], t->center[1], t->center[2]);
}
t->snap[0] = 0.0f;
t->snap[1] = G.vd->gridview * 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
}
else if(t->spacetype == SPACE_IMAGE) {
t->snap[0] = 0.0f;
t->snap[1] = 0.125f;
t->snap[2] = 0.0625f;
}
else {
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
}
}
2005-03-14 20:10:22 +00:00
static void headerTranslation(TransInfo *t, float vec[3], char *str) {
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
char tvec[60];
char distvec[20];
char autoik[20];
float dvec[3];
float dist;
convertVecToDisplayNum(vec, dvec);
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
dist = VecLength(t->num.val);
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
}
else {
dist = VecLength(vec);
sprintf(&tvec[0], "%.4f", dvec[0]);
sprintf(&tvec[20], "%.4f", dvec[1]);
sprintf(&tvec[40], "%.4f", dvec[2]);
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
}
if( dist > 1e10 || dist < -1e10 ) /* prevent string buffer overflow */
sprintf(distvec, "%.4e", dist);
else
sprintf(distvec, "%.4f", dist);
if(t->flag & T_AUTOIK) {
short chainlen= G.scene->toolsettings->autoik_chainlen;
if(chainlen)
sprintf(autoik, "AutoIK-Len: %d", chainlen);
else
strcpy(autoik, "");
}
else
strcpy(autoik, "");
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
if (t->con.mode & CON_APPLY) {
switch(t->num.idx_max) {
case 0:
sprintf(str, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]);
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
break;
case 1:
sprintf(str, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext, &autoik[0]);
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
break;
case 2:
sprintf(str, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]);
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
}
}
else {
if(t->flag & T_2D_EDIT)
sprintf(str, "Dx: %s Dy: %s (%s)%s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext);
else
sprintf(str, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]);
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
}
}
2005-03-14 20:10:22 +00:00
static void applyTranslation(TransInfo *t, float vec[3]) {
TransData *td = t->data;
float tvec[3];
int i;
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
/* handle snapping rotation before doing the translation */
if (usingSnappingNormal(t))
{
if (validSnappingNormal(t))
{
float *original_normal = td->axismtx[2];
float axis[3];
float quat[4];
float mat[3][3];
float angle;
Crossf(axis, original_normal, t->tsnap.snapNormal);
angle = saacos(Inpf(original_normal, t->tsnap.snapNormal));
AxisAngleToQuat(quat, axis, angle);
QuatToMat3(quat, mat);
ElementRotation(t, td, mat, V3D_LOCAL);
}
else
{
float mat[3][3];
Mat3One(mat);
ElementRotation(t, td, mat, V3D_LOCAL);
}
}
if (t->con.applyVec) {
+ Local axis constraint for multiple object selection works with resize and rotate (the easiest). + Refined the headerprint for Translation. Now prints only the needed info for constraint in the constraint's space (ie: if you're moving 1 unit along the local X axis, regardless of it's orientation, it will print "D: 1.000 along local X") Still need to make numinput work like that (typing a number with a local axis constraint would move along that axis. There's some base code already though, just need a finishing touch, but it's late now) + Optimised PET calculations by using the TD_NOACTION flag (actually, that might have been in the last commit). + Added a float axismtx[3][3] member to TransData to store the orientation of the element (useful for local axis constrainst which, in edit could be moving along normals and the like). - Fixed scaling in edit mode (was doing some matrix multiplications in the wrong order, only visible when using a constraint) - Fixed the constraint projection matrix. It didn't work for planar constraint if the constraint space wasn't global (in a nutshell, it produced weird results for local space planes). - Some potential bugs fixed (Note to Ton: added an ext pointer in TransInfo to point to the TransDataExtension block. With the sort done after allocation, the first td pointer doesn't necesarely point at the start of the ext block, so we needed another to free it correctly). - Got rid of some remaining test with G.obedit. - Moved constraint reset from init to post trans code (Ton, that means you can create constraints before calling transform, like for the menus for example). NOTE: I was getting some random segfault with the new headerprint code. Very random, couldn't reproduce with a debug version. I did some initialisation that might have been missing (though doubtful that's what caused the crashes). Was linked to using constraint though not caused by them. Probably due to some dumb late coding error.
2005-03-08 03:51:45 +00:00
float pvec[3];
t->con.applyVec(t, td, vec, tvec, pvec);
}
else {
VECCOPY(tvec, vec);
}
Mat3MulVecfl(td->smtx, tvec);
VecMulf(tvec, td->factor);
protectedTransBits(td->protectflag, tvec);
/* transdata ipokey */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
add_tdi_poin(tdi->locx, tdi->oldloc, tvec[0]);
add_tdi_poin(tdi->locy, tdi->oldloc+1, tvec[1]);
add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]);
}
else VecAddf(td->loc, td->iloc, tvec);
constraintTransLim(t, td);
}
}
/* uses t->vec to store actual translation in */
int Translation(TransInfo *t, short mval[2])
{
float tvec[3];
char str[250];
if(t->flag & T_SHIFT_MOD) {
float dvec[3];
/* calculate the main translation and the precise one separate */
convertViewVec(t, dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1]));
VecMulf(dvec, 0.1f);
convertViewVec(t, t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1]));
VecAddf(t->vec, t->vec, dvec);
}
else convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
applySnapping(t, t->vec);
t->con.applyVec(t, NULL, t->vec, tvec, pvec);
VECCOPY(t->vec, tvec);
headerTranslation(t, pvec, str);
}
else {
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
applyNDofInput(&t->ndof, t->vec);
snapGrid(t, t->vec);
applyNumInput(&t->num, t->vec);
applySnapping(t, t->vec);
headerTranslation(t, t->vec, str);
}
applyTranslation(t, t->vec);
/* evil hack - redo translation if cliiping needeed */
if (t->flag & T_CLIP_UV && clipUVTransform(t, t->vec, 0))
applyTranslation(t, t->vec);
recalcData(t);
headerprint(str);
viewRedrawForce(t);
drawSnapping(t);
return 1;
}
/* ************************** SHRINK/FATTEN *************************** */
void initShrinkFatten(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
// If not in mesh edit mode, fallback to Resize
if (G.obedit==NULL || G.obedit->type != OB_MESH) {
initResize(t);
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
else {
t->mode = TFM_SHRINKFATTEN;
t->transform = ShrinkFatten;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
t->flag |= T_NO_CONSTRAINT;
}
}
int ShrinkFatten(TransInfo *t, short mval[2])
{
float vec[3];
float distance;
int i;
char str[64];
TransData *td = t->data;
distance = -InputVerticalAbsolute(t, mval);
snapGrid(t, &distance);
applyNumInput(&t->num, &distance);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "Shrink/Fatten: %s %s", c, t->proptext);
}
else {
/* default header print */
sprintf(str, "Shrink/Fatten: %.4f %s", distance, t->proptext);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
VECCOPY(vec, td->axismtx[2]);
VecMulf(vec, distance);
VecMulf(vec, td->factor);
VecAddf(td->loc, td->iloc, vec);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
return 1;
}
/* ************************** TILT *************************** */
void initTilt(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_TILT;
t->transform = Tilt;
t->ndof.axis = 16;
/* Scale down and flip input for rotation */
t->ndof.factor[0] = -0.2f;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
t->fac = 0;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
}
int Tilt(TransInfo *t, short mval[2])
{
TransData *td = t->data;
int i;
char str[50];
float final;
t->fac += InputDeltaAngle(t, mval);
final = t->fac;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
applyNDofInput(&t->ndof, &final);
snapGrid(t, &final);
if (hasNumInput(&t->num)) {
char c[20];
applyNumInput(&t->num, &final);
outputNumInput(&(t->num), c);
sprintf(str, "Tilt: %s %s", &c[0], t->proptext);
final *= (float)(M_PI / 180.0);
}
else {
sprintf(str, "Tilt: %.2f %s", 180.0*final/M_PI, t->proptext);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (td->val) {
*td->val = td->ival + final * td->factor;
}
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
helpline (t, t->center);
return 1;
}
/* ******************** Curve Shrink/Fatten *************** */
int CurveShrinkFatten(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float ratio;
int i;
char str[50];
if(t->flag & T_SHIFT_MOD) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
float dx= (float)(t->center2d[0] - t->shiftmval[0]);
float dy= (float)(t->center2d[1] - t->shiftmval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
dx= (float)(t->center2d[0] - mval[0]);
dy= (float)(t->center2d[1] - mval[1]);
ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
}
else {
float dx= (float)(t->center2d[0] - mval[0]);
float dy= (float)(t->center2d[1] - mval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
}
snapGrid(t, &ratio);
applyNumInput(&t->num, &ratio);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "Shrink/Fatten: %s", c);
}
else {
sprintf(str, "Shrink/Fatten: %3f", ratio);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if(td->val) {
//*td->val= ratio;
*td->val= td->ival*ratio;
if (*td->val <= 0.0f) *td->val = 0.0001f;
}
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
return 1;
}
void initCurveShrinkFatten(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_CURVE_SHRINKFATTEN;
t->transform = CurveShrinkFatten;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
t->fac = (float)sqrt( (
((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+
((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
) );
}
/* ************************** PUSH/PULL *************************** */
void initPushPull(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_PUSHPULL;
t->transform = PushPull;
t->ndof.axis = 4;
/* Flip direction */
t->ndof.factor[0] = -1.0f;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
}
int PushPull(TransInfo *t, short mval[2])
{
float vec[3], axis[3];
float distance;
int i;
char str[128];
TransData *td = t->data;
distance = InputVerticalAbsolute(t, mval);
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
applyNDofInput(&t->ndof, &distance);
snapGrid(t, &distance);
applyNumInput(&t->num, &distance);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "Push/Pull: %s%s %s", c, t->con.text, t->proptext);
}
else {
/* default header print */
sprintf(str, "Push/Pull: %.4f%s %s", distance, t->con.text, t->proptext);
}
if (t->con.applyRot && t->con.mode & CON_APPLY) {
t->con.applyRot(t, NULL, axis, NULL);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
VecSubf(vec, t->center, td->center);
if (t->con.applyRot && t->con.mode & CON_APPLY) {
t->con.applyRot(t, td, axis, NULL);
if (isLockConstraint(t)) {
float dvec[3];
Projf(dvec, vec, axis);
VecSubf(vec, vec, dvec);
}
else {
Projf(vec, vec, axis);
}
}
Normalize(vec);
VecMulf(vec, distance);
VecMulf(vec, td->factor);
VecAddf(td->loc, td->iloc, vec);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
return 1;
}
/* ************************** BEVEL **************************** */
void initBevel(TransInfo *t)
{
t->mode = TFM_BEVEL;
t->flag |= T_NO_CONSTRAINT;
t->num.flag |= NUM_NO_NEGATIVE;
t->transform = Bevel;
t->handleEvent = handleEventBevel;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
/* DON'T KNOW WHY THIS IS NEEDED */
if (G.editBMesh->imval[0] == 0 && G.editBMesh->imval[1] == 0) {
/* save the initial mouse co */
G.editBMesh->imval[0] = t->imval[0];
G.editBMesh->imval[1] = t->imval[1];
}
else {
/* restore the mouse co from a previous call to initTransform() */
t->imval[0] = G.editBMesh->imval[0];
t->imval[1] = G.editBMesh->imval[1];
}
}
int handleEventBevel(TransInfo *t, unsigned short event, short val)
{
if (val) {
if(!G.editBMesh) return 0;
switch (event) {
case MIDDLEMOUSE:
G.editBMesh->options ^= BME_BEVEL_VERT;
t->state = TRANS_CANCEL;
return 1;
//case PADPLUSKEY:
// G.editBMesh->options ^= BME_BEVEL_RES;
// G.editBMesh->res += 1;
// if (G.editBMesh->res > 4) {
// G.editBMesh->res = 4;
// }
// t->state = TRANS_CANCEL;
// return 1;
//case PADMINUS:
// G.editBMesh->options ^= BME_BEVEL_RES;
// G.editBMesh->res -= 1;
// if (G.editBMesh->res < 0) {
// G.editBMesh->res = 0;
// }
// t->state = TRANS_CANCEL;
// return 1;
default:
return 0;
}
}
return 0;
}
int Bevel(TransInfo *t, short mval[2])
{
float distance,d;
int i;
char str[128];
char *mode;
TransData *td = t->data;
mode = (G.editBMesh->options & BME_BEVEL_VERT) ? "verts only" : "normal";
distance = InputHorizontalAbsolute(t, mval)/4; /* 4 just seemed a nice value to me, nothing special */
distance = fabs(distance);
snapGrid(t, &distance);
applyNumInput(&t->num, &distance);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "Bevel - Dist: %s, Mode: %s (MMB to toggle))", c, mode);
}
else {
/* default header print */
sprintf(str, "Bevel - Dist: %.4f, Mode: %s (MMB to toggle))", distance, mode);
}
if (distance < 0) distance = -distance;
for(i = 0 ; i < t->total; i++, td++) {
if (td->axismtx[1][0] > 0 && distance > td->axismtx[1][0]) {
d = td->axismtx[1][0];
}
else {
d = distance;
}
VECADDFAC(td->loc,td->center,td->axismtx[0],(*td->val)*d);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
return 1;
}
/* ************************** BEVEL WEIGHT *************************** */
void initBevelWeight(TransInfo *t)
{
t->mode = TFM_BWEIGHT;
t->transform = BevelWeight;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
t->flag |= T_NO_CONSTRAINT;
t->fac = (float)sqrt(
(
((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+
((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
) );
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
int BevelWeight(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float weight;
int i;
char str[50];
if(t->flag & T_SHIFT_MOD) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
float dx= (float)(t->center2d[0] - t->shiftmval[0]);
float dy= (float)(t->center2d[1] - t->shiftmval[1]);
weight = (float)sqrt( dx*dx + dy*dy)/t->fac;
dx= (float)(t->center2d[0] - mval[0]);
dy= (float)(t->center2d[1] - mval[1]);
weight+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -weight);
}
else {
float dx= (float)(t->center2d[0] - mval[0]);
float dy= (float)(t->center2d[1] - mval[1]);
weight = (float)sqrt( dx*dx + dy*dy)/t->fac;
}
weight -= 1.0f;
if (weight > 1.0f) weight = 1.0f;
snapGrid(t, &weight);
applyNumInput(&t->num, &weight);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
if (weight >= 0.0f)
sprintf(str, "Bevel Weight: +%s %s", c, t->proptext);
else
sprintf(str, "Bevel Weight: %s %s", c, t->proptext);
}
else {
/* default header print */
if (weight >= 0.0f)
sprintf(str, "Bevel Weight: +%.3f %s", weight, t->proptext);
else
sprintf(str, "Bevel Weight: %.3f %s", weight, t->proptext);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->val) {
*td->val = td->ival + weight * td->factor;
if (*td->val < 0.0f) *td->val = 0.0f;
if (*td->val > 1.0f) *td->val = 1.0f;
}
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
helpline (t, t->center);
return 1;
}
/* ************************** CREASE *************************** */
void initCrease(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_CREASE;
t->transform = Crease;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
t->fac = (float)sqrt(
(
((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+
((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
) );
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
int Crease(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float crease;
int i;
char str[50];
if(t->flag & T_SHIFT_MOD) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
float dx= (float)(t->center2d[0] - t->shiftmval[0]);
float dy= (float)(t->center2d[1] - t->shiftmval[1]);
crease = (float)sqrt( dx*dx + dy*dy)/t->fac;
dx= (float)(t->center2d[0] - mval[0]);
dy= (float)(t->center2d[1] - mval[1]);
crease+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -crease);
}
else {
float dx= (float)(t->center2d[0] - mval[0]);
float dy= (float)(t->center2d[1] - mval[1]);
crease = (float)sqrt( dx*dx + dy*dy)/t->fac;
}
crease -= 1.0f;
if (crease > 1.0f) crease = 1.0f;
snapGrid(t, &crease);
applyNumInput(&t->num, &crease);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
if (crease >= 0.0f)
sprintf(str, "Crease: +%s %s", c, t->proptext);
else
sprintf(str, "Crease: %s %s", c, t->proptext);
}
else {
/* default header print */
if (crease >= 0.0f)
sprintf(str, "Crease: +%.3f %s", crease, t->proptext);
else
sprintf(str, "Crease: %.3f %s", crease, t->proptext);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (td->val) {
*td->val = td->ival + crease * td->factor;
if (*td->val < 0.0f) *td->val = 0.0f;
if (*td->val > 1.0f) *td->val = 1.0f;
}
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
helpline (t, t->center);
return 1;
}
/* ******************** EditBone (B-bone) width scaling *************** */
void initBoneSize(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_BONESIZE;
t->transform = BoneSize;
t->idx_max = 2;
t->num.idx_max = 2;
t->num.flag |= NUM_NULL_ONE;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
t->fac = (float)sqrt( (
((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+
((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
) );
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
static void headerBoneSize(TransInfo *t, float vec[3], char *str) {
char tvec[60];
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
else {
sprintf(&tvec[0], "%.4f", vec[0]);
sprintf(&tvec[20], "%.4f", vec[1]);
sprintf(&tvec[40], "%.4f", vec[2]);
}
/* hmm... perhaps the y-axis values don't need to be shown? */
if (t->con.mode & CON_APPLY) {
if (t->num.idx_max == 0)
sprintf(str, "ScaleB: %s%s %s", &tvec[0], t->con.text, t->proptext);
else
sprintf(str, "ScaleB: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
}
else {
sprintf(str, "ScaleB X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
}
}
static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
{
float tmat[3][3], smat[3][3], oldy;
float sizemat[3][3];
Mat3MulMat3(smat, mat, td->mtx);
Mat3MulMat3(tmat, td->smtx, smat);
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
}
/* we've tucked the scale in loc */
oldy= td->iloc[1];
SizeToMat3(td->iloc, sizemat);
Mat3MulMat3(tmat, tmat, sizemat);
Mat3ToSize(tmat, td->loc);
td->loc[1]= oldy;
}
int BoneSize(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float size[3], mat[3][3];
float ratio;
int i;
char str[60];
/* for manipulator, center handle, the scaling can't be done relative to center */
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) {
ratio = 1.0f - ((t->imval[0] - mval[0]) + (t->imval[1] - mval[1]))/100.0f;
}
else {
if(t->flag & T_SHIFT_MOD) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
float dx= (float)(t->center2d[0] - t->shiftmval[0]);
float dy= (float)(t->center2d[1] - t->shiftmval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
dx= (float)(t->center2d[0] - mval[0]);
dy= (float)(t->center2d[1] - mval[1]);
ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
}
else {
float dx= (float)(t->center2d[0] - mval[0]);
float dy= (float)(t->center2d[1] - mval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
}
/* flip scale, but not for manipulator center handle */
if ((t->center2d[0] - mval[0]) * (t->center2d[0] - t->imval[0]) +
(t->center2d[1] - mval[1]) * (t->center2d[1] - t->imval[1]) < 0)
ratio *= -1.0f;
}
size[0] = size[1] = size[2] = ratio;
snapGrid(t, size);
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, size);
constraintNumInput(t, size);
}
SizeToMat3(size, mat);
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
Mat3CpyMat3(t->mat, mat); // used in manipulator
headerBoneSize(t, size, str);
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
ElementBoneSize(t, td, mat);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
return 1;
}
/* ******************** EditBone envelope *************** */
void initBoneEnvelope(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_BONE_ENVELOPE;
t->transform = BoneEnvelope;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
t->fac = (float)sqrt( (
((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+
((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
) );
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
int BoneEnvelope(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float ratio;
int i;
char str[50];
if(t->flag & T_SHIFT_MOD) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
float dx= (float)(t->center2d[0] - t->shiftmval[0]);
float dy= (float)(t->center2d[1] - t->shiftmval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
dx= (float)(t->center2d[0] - mval[0]);
dy= (float)(t->center2d[1] - mval[1]);
ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
}
else {
float dx= (float)(t->center2d[0] - mval[0]);
float dy= (float)(t->center2d[1] - mval[1]);
ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
}
snapGrid(t, &ratio);
applyNumInput(&t->num, &ratio);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
sprintf(str, "Envelope: %s", c);
}
else {
sprintf(str, "Envelope: %3f", ratio);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (td->val) {
/* if the old/original value was 0.0f, then just use ratio */
if (td->ival)
*td->val= td->ival*ratio;
else
*td->val= ratio;
}
}
recalcData(t);
headerprint(str);
force_draw(0);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
return 1;
}
/* ******************** EditBone roll *************** */
void initBoneRoll(TransInfo *t)
{
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->mode = TFM_BONE_ROLL;
t->transform = BoneRoll;
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
t->fac = 0.0f;
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
t->flag |= T_NO_CONSTRAINT;
}
int BoneRoll(TransInfo *t, short mval[2])
{
TransData *td = t->data;
int i;
char str[50];
float final;
t->fac += InputDeltaAngle(t, mval);
final = t->fac;
snapGrid(t, &final);
if (hasNumInput(&t->num)) {
char c[20];
applyNumInput(&t->num, &final);
outputNumInput(&(t->num), c);
sprintf(str, "Roll: %s", &c[0]);
final *= (float)(M_PI / 180.0);
}
else {
sprintf(str, "Roll: %.2f", 180.0*final/M_PI);
}
/* set roll values */
for (i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
*(td->val) = td->ival - final;
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
return 1;
}
/* ************************** BAKE TIME ******************* */
void initBakeTime(TransInfo *t)
{
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
t->transform = BakeTime;
t->fac = 0.1f;
}
int BakeTime(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float time;
int i;
char str[50];
if(t->flag & T_SHIFT_MOD) {
/* calculate ratio for shiftkey pos, and for total, and blend these for precision */
time= (float)(t->center2d[0] - t->shiftmval[0])*t->fac;
time+= 0.1f*((float)(t->center2d[0]*t->fac - mval[0]) -time);
}
else {
time = (float)(t->center2d[0] - mval[0])*t->fac;
}
snapGrid(t, &time);
applyNumInput(&t->num, &time);
/* header print for NumInput */
if (hasNumInput(&t->num)) {
char c[20];
outputNumInput(&(t->num), c);
if (time >= 0.0f)
sprintf(str, "Time: +%s %s", c, t->proptext);
else
sprintf(str, "Time: %s %s", c, t->proptext);
}
else {
/* default header print */
if (time >= 0.0f)
sprintf(str, "Time: +%.3f %s", time, t->proptext);
else
sprintf(str, "Time: %.3f %s", time, t->proptext);
}
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (td->val) {
*td->val = td->ival + time * td->factor;
if (td->ext->size && *td->val < *td->ext->size) *td->val = *td->ext->size;
if (td->ext->quat && *td->val > *td->ext->quat) *td->val = *td->ext->quat;
}
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
helpline (t, t->center);
return 1;
}
/* ************************** MIRROR *************************** */
void initMirror(TransInfo *t)
{
t->flag |= T_NULL_ONE;
if (!G.obedit) {
t->flag |= T_NO_ZERO;
}
t->transform = Mirror;
}
int Mirror(TransInfo *t, short mval[2])
{
TransData *td;
float size[3], mat[3][3];
int i;
char str[200];
/*
* OPTIMISATION:
* This still recalcs transformation on mouse move
* while it should only recalc on constraint change
* */
/* if an axis has been selected */
if (t->con.mode & CON_APPLY) {
size[0] = size[1] = size[2] = -1;
SizeToMat3(size, mat);
if (t->con.applySize) {
t->con.applySize(t, NULL, mat);
}
sprintf(str, "Mirror%s", t->con.text);
for(i = 0, td=t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
ElementResize(t, td, mat);
}
recalcData(t);
headerprint(str);
viewRedrawForce(t);
}
else
{
size[0] = size[1] = size[2] = 1;
SizeToMat3(size, mat);
for(i = 0, td=t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
ElementResize(t, td, mat);
}
recalcData(t);
headerprint("Select a mirror axis (X, Y, Z)");
viewRedrawForce(t);
}
return 1;
}
/* ************************** ALIGN *************************** */
void initAlign(TransInfo *t)
{
t->flag |= T_NO_CONSTRAINT;
t->transform = Align;
}
int Align(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float center[3];
int i;
/* saving original center */
VECCOPY(center, t->center);
for(i = 0 ; i < t->total; i++, td++)
{
float mat[3][3], invmat[3][3];
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
/* around local centers */
if (t->flag & (T_OBJECT|T_POSE)) {
VECCOPY(t->center, td->center);
}
else {
if(G.scene->selectmode & SCE_SELECT_FACE) {
VECCOPY(t->center, td->center);
}
}
Mat3Inv(invmat, td->axismtx);
Mat3MulMat3(mat, t->spacemtx, invmat);
ElementRotation(t, td, mat, t->around);
}
/* restoring original center */
VECCOPY(t->center, center);
recalcData(t);
headerprint("Align");
return 1;
}
/* ************************** ANIM EDITORS - TRANSFORM TOOLS *************************** */
/* ---------------- Special Helpers for Various Settings ------------- */
/* This function returns the snapping 'mode' for Animation Editors only
* We cannot use the standard snapping due to NLA-strip scaling complexities.
*/
static short getAnimEdit_SnapMode(TransInfo *t)
{
short autosnap= SACTSNAP_OFF;
/* currently, some of these are only for the action editor */
if (t->spacetype == SPACE_ACTION && G.saction) {
switch (G.saction->autosnap) {
case SACTSNAP_OFF:
if (G.qual == LR_CTRLKEY)
autosnap= SACTSNAP_STEP;
else if (G.qual == LR_SHIFTKEY)
autosnap= SACTSNAP_FRAME;
else if (G.qual == LR_ALTKEY)
autosnap= SACTSNAP_MARKER;
else
autosnap= SACTSNAP_OFF;
break;
case SACTSNAP_STEP:
autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_STEP;
break;
case SACTSNAP_FRAME:
autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
break;
case SACTSNAP_MARKER:
autosnap= (G.qual==LR_ALTKEY)? SACTSNAP_OFF: SACTSNAP_MARKER;
break;
}
}
else if (t->spacetype == SPACE_NLA && G.snla) {
switch (G.snla->autosnap) {
case SACTSNAP_OFF:
if (G.qual == LR_CTRLKEY)
autosnap= SACTSNAP_STEP;
else if (G.qual == LR_SHIFTKEY)
autosnap= SACTSNAP_FRAME;
else if (G.qual == LR_ALTKEY)
autosnap= SACTSNAP_MARKER;
else
autosnap= SACTSNAP_OFF;
break;
case SACTSNAP_STEP:
autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_STEP;
break;
case SACTSNAP_FRAME:
autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
break;
case SACTSNAP_MARKER:
autosnap= (G.qual==LR_ALTKEY)? SACTSNAP_OFF: SACTSNAP_MARKER;
break;
}
}
else {
if (G.qual == LR_CTRLKEY)
autosnap= SACTSNAP_STEP;
else if (G.qual == LR_SHIFTKEY)
autosnap= SACTSNAP_FRAME;
else if (G.qual == LR_ALTKEY)
autosnap= SACTSNAP_MARKER;
else
autosnap= SACTSNAP_OFF;
}
return autosnap;
}
/* This function is used for testing if an Animation Editor is displaying
* its data in frames or seconds (and the data needing to be edited as such).
* Returns 1 if in seconds, 0 if in frames
*/
static short getAnimEdit_DrawTime(TransInfo *t)
{
short drawtime;
/* currently, some of these are only for the action editor */
if (t->spacetype == SPACE_ACTION && G.saction) {
drawtime = (G.saction->flag & SACTION_DRAWTIME)? 1 : 0;
}
2007-09-24 12:25:13 +00:00
else if (t->spacetype == SPACE_NLA && G.snla) {
drawtime = (G.snla->flag & SNLA_DRAWTIME)? 1 : 0;
}
else {
drawtime = 0;
}
return drawtime;
}
/* This function is used by Animation Editor specific transform functions to do
* the Snap Keyframe to Nearest Frame/Marker
*/
static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, Object *ob, short autosnap)
{
/* snap key to nearest frame? */
if (autosnap == SACTSNAP_FRAME) {
short doTime= getAnimEdit_DrawTime(t);
double secf= FPS;
2008-03-27 05:12:14 +00:00
double val;
/* convert frame to nla-action time (if needed) */
if (ob)
val= get_action_frame_inv(ob, *(td->val));
else
val= *(td->val);
/* do the snapping to nearest frame/second */
if (doTime)
val= (float)( floor((val/secf) + 0.5f) * secf );
else
val= (float)( floor(val+0.5f) );
/* convert frame out of nla-action time */
if (ob)
*(td->val)= get_action_frame(ob, val);
else
*(td->val)= val;
}
/* snap key to nearest marker? */
else if (autosnap == SACTSNAP_MARKER) {
float val;
/* convert frame to nla-action time (if needed) */
if (ob)
val= get_action_frame_inv(ob, *(td->val));
else
val= *(td->val);
/* snap to nearest marker */
val= (float)find_nearest_marker_time(val);
/* convert frame out of nla-action time */
if (ob)
*(td->val)= get_action_frame(ob, val);
else
*(td->val)= val;
}
}
/* ----------------- Translation ----------------------- */
void initTimeTranslate(TransInfo *t)
{
t->mode = TFM_TIME_TRANSLATE;
t->transform = TimeTranslate;
/* num-input has max of (n-1) */
t->idx_max = 0;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
}
static void headerTimeTranslate(TransInfo *t, char *str)
{
char tvec[60];
/* if numeric input is active, use results from that, otherwise apply snapping to result */
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
else {
short autosnap= getAnimEdit_SnapMode(t);
short doTime = getAnimEdit_DrawTime(t);
double secf= FPS;
float val= t->fac;
/* apply snapping + frame->seconds conversions */
if (autosnap == SACTSNAP_STEP) {
if (doTime)
val= floor(val/secf + 0.5f);
else
val= floor(val + 0.5f);
}
else {
if (doTime)
val= val / secf;
}
sprintf(&tvec[0], "%.4f", val);
}
sprintf(str, "DeltaX: %s", &tvec[0]);
}
static void applyTimeTranslate(TransInfo *t, float sval)
{
TransData *td = t->data;
int i;
short doTime= getAnimEdit_DrawTime(t);
double secf= FPS;
short autosnap= getAnimEdit_SnapMode(t);
float deltax, val;
/* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
for (i = 0 ; i < t->total; i++, td++) {
/* it is assumed that td->ob is a pointer to the object,
* whose active action is where this keyframe comes from
*/
Object *ob= td->ob;
/* check if any need to apply nla-scaling */
if (ob) {
deltax = t->fac;
if (autosnap == SACTSNAP_STEP) {
if (doTime)
deltax= (float)( floor((deltax/secf) + 0.5f) * secf );
else
deltax= (float)( floor(deltax + 0.5f) );
}
val = get_action_frame_inv(ob, td->ival);
val += deltax;
*(td->val) = get_action_frame(ob, val);
}
else {
deltax = val = t->fac;
if (autosnap == SACTSNAP_STEP) {
if (doTime)
val= (float)( floor((deltax/secf) + 0.5f) * secf );
else
val= (float)( floor(val + 0.5f) );
}
*(td->val) = td->ival + val;
}
/* apply nearest snapping */
doAnimEdit_SnapFrame(t, td, ob, autosnap);
}
}
int TimeTranslate(TransInfo *t, short mval[2])
{
float cval[2], sval[2];
char str[200];
/* calculate translation amount from mouse movement - in 'time-grid space' */
areamouseco_to_ipoco(G.v2d, mval, &cval[0], &cval[1]);
areamouseco_to_ipoco(G.v2d, t->imval, &sval[0], &sval[1]);
/* we only need to calculate effect for time (applyTimeTranslate only needs that) */
t->fac= cval[0] - sval[0];
/* handle numeric-input stuff */
t->vec[0] = t->fac;
applyNumInput(&t->num, &t->vec[0]);
t->fac = t->vec[0];
headerTimeTranslate(t, str);
applyTimeTranslate(t, sval[0]);
recalcData(t);
headerprint(str);
viewRedrawForce(t);
return 1;
}
/* ----------------- Time Slide ----------------------- */
void initTimeSlide(TransInfo *t)
{
/* this tool is only really available in the Action Editor... */
if (t->spacetype == SPACE_ACTION) {
/* set flag for drawing stuff*/
G.saction->flag |= SACTION_MOVING;
}
t->mode = TFM_TIME_SLIDE;
t->transform = TimeSlide;
t->flag |= T_FREE_CUSTOMDATA;
/* num-input has max of (n-1) */
t->idx_max = 0;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
}
static void headerTimeSlide(TransInfo *t, float sval, char *str)
{
char tvec[60];
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
else {
float minx= *((float *)(t->customData));
float maxx= *((float *)(t->customData) + 1);
float cval= t->fac;
float val;
val= 2.0*(cval-sval) / (maxx-minx);
CLAMP(val, -1.0f, 1.0f);
sprintf(&tvec[0], "%.4f", val);
}
sprintf(str, "TimeSlide: %s", &tvec[0]);
}
static void applyTimeSlide(TransInfo *t, float sval)
{
TransData *td = t->data;
int i;
float minx= *((float *)(t->customData));
float maxx= *((float *)(t->customData) + 1);
/* set value for drawing black line */
if (t->spacetype == SPACE_ACTION) {
float cvalf = t->fac;
if (NLA_ACTION_SCALED)
cvalf= get_action_frame(OBACT, cvalf);
G.saction->timeslide= cvalf;
}
/* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
for (i = 0 ; i < t->total; i++, td++) {
/* it is assumed that td->ob is a pointer to the object,
* whose active action is where this keyframe comes from
*/
Object *ob= td->ob;
float cval = t->fac;
/* apply scaling to necessary values */
if (ob)
cval= get_action_frame(ob, cval);
/* only apply to data if in range */
if ((sval > minx) && (sval < maxx)) {
float cvalc= CLAMPIS(cval, minx, maxx);
float timefac;
/* left half? */
if (td->ival < sval) {
timefac= (sval - td->ival) / (sval - minx);
*(td->val)= cvalc - timefac * (cvalc - minx);
}
else {
timefac= (td->ival - sval) / (maxx - sval);
*(td->val)= cvalc + timefac * (maxx - cvalc);
}
}
}
}
int TimeSlide(TransInfo *t, short mval[2])
{
float cval[2], sval[2];
float minx= *((float *)(t->customData));
float maxx= *((float *)(t->customData) + 1);
char str[200];
/* calculate mouse co-ordinates */
areamouseco_to_ipoco(G.v2d, mval, &cval[0], &cval[1]);
areamouseco_to_ipoco(G.v2d, t->imval, &sval[0], &sval[1]);
/* t->fac stores cval[0], which is the current mouse-pointer location (in frames) */
t->fac= cval[0];
/* handle numeric-input stuff */
t->vec[0] = 2.0*(cval[0]-sval[0]) / (maxx-minx);
applyNumInput(&t->num, &t->vec[0]);
t->fac = (maxx-minx) * t->vec[0] / 2.0 + sval[0];
headerTimeSlide(t, sval[0], str);
applyTimeSlide(t, sval[0]);
recalcData(t);
headerprint(str);
viewRedrawForce(t);
return 1;
}
/* ----------------- Scaling ----------------------- */
void initTimeScale(TransInfo *t)
{
t->mode = TFM_TIME_SCALE;
t->transform = TimeScale;
t->flag |= T_NULL_ONE;
t->num.flag |= NUM_NULL_ONE;
/* num-input has max of (n-1) */
t->idx_max = 0;
t->num.flag = 0;
t->num.idx_max = t->idx_max;
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
}
static void headerTimeScale(TransInfo *t, char *str) {
char tvec[60];
if (hasNumInput(&t->num))
outputNumInput(&(t->num), tvec);
else
sprintf(&tvec[0], "%.4f", t->fac);
sprintf(str, "ScaleX: %s", &tvec[0]);
}
static void applyTimeScale(TransInfo *t) {
TransData *td = t->data;
int i;
short autosnap= getAnimEdit_SnapMode(t);
short doTime= getAnimEdit_DrawTime(t);
double secf= FPS;
for (i = 0 ; i < t->total; i++, td++) {
/* it is assumed that td->ob is a pointer to the object,
* whose active action is where this keyframe comes from
*/
Object *ob= td->ob;
float startx= CFRA;
float fac= t->fac;
if (autosnap == SACTSNAP_STEP) {
if (doTime)
fac= (float)( floor(fac/secf + 0.5f) * secf );
else
fac= (float)( floor(fac + 0.5f) );
}
/* check if any need to apply nla-scaling */
if (ob)
startx= get_action_frame(ob, startx);
/* now, calculate the new value */
*(td->val) = td->ival - startx;
*(td->val) *= fac;
*(td->val) += startx;
/* apply nearest snapping */
doAnimEdit_SnapFrame(t, td, ob, autosnap);
}
}
int TimeScale(TransInfo *t, short mval[2])
{
float cval, sval;
float deltax, startx;
float width= 0.0f;
char str[200];
sval= t->imval[0];
cval= mval[0];
switch (t->spacetype) {
case SPACE_ACTION:
width= ACTWIDTH;
break;
case SPACE_NLA:
width= NLAWIDTH;
break;
}
/* calculate scaling factor */
startx= sval-(width/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
deltax= cval-(width/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
t->fac = deltax / startx;
/* handle numeric-input stuff */
t->vec[0] = t->fac;
applyNumInput(&t->num, &t->vec[0]);
t->fac = t->vec[0];
headerTimeScale(t, str);
applyTimeScale(t);
recalcData(t);
headerprint(str);
viewRedrawForce(t);
return 1;
}
/* ************************************ */
void BIF_TransformSetUndo(char *str)
{
Trans.undostr= str;
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
void NDofTransform()
{
float fval[7];
float maxval = 50.0f; // also serves as threshold
int axis = -1;
int mode = 0;
int i;
getndof(fval);
for(i = 0; i < 6; i++)
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
{
float val = fabs(fval[i]);
if (val > maxval)
{
axis = i;
maxval = val;
}
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
switch(axis)
{
case -1:
/* No proper axis found */
break;
case 0:
case 1:
case 2:
mode = TFM_TRANSLATION;
break;
case 4:
mode = TFM_ROTATION;
break;
case 3:
case 5:
mode = TFM_TRACKBALL;
break;
default:
printf("ndof: what we are doing here ?");
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
if (mode != 0)
{
initTransform(mode, CTX_NDOF);
Transform();
}
Some cleanup of the ndof functions: Moving filterNDOFvalues and getndof to editscreen.c/BIF_mywindow.h (this might not be the best spot but it matches table/mouse functions) Adding missing function definition in include files and fix declaration mixup (void functions used as int, short pointer used as float pointer) New NDofInput model for transform (reusable externally in the future): Handles ndof events, accumulates values and enables remapping and rescaling values to fit any axis combinaison into a float[3] (this could be extended in the future, also, it doesn't support out of order axis right now). Compatible with "gears" (Ctrl key) New transform context for pure NDof input transform (entered when using Transform mode on the device). In this mode, transform "transactions" are automatically confirmed when the device returns to its rest position Rotation on Z triggers a rotation (axis is perpendicular to the screen as usual, constraints works as expected) Rotation on X/Y triggers trackball rotation Translation on X/Y/Z triggers translation (doesn't support constraints correctly). The device can also be used during a "normal" transform operation. In this case, there is no auto confirm but button 1 (right) can be used to confirm while button 2 is used to clear the NDof input (back to mouse input). NDof support was added to translation, rotation and trackball (as previously mentionned) but also to Tilt (same as rotation) and Push/Pull (move device along Z axis). This is a bit preliminary work, so everyone should feel free to comment and send suggestions. NOTE: this commit also merges revision 11523 from the trunk
2007-08-30 22:02:32 +00:00
}