[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13400] trunk/blender/source/blender: == Limit Distance Constraint ==

Joshua Leung aligorith at gmail.com
Fri Jan 25 12:23:37 CET 2008


Revision: 13400
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13400
Author:   aligorith
Date:     2008-01-25 12:23:36 +0100 (Fri, 25 Jan 2008)

Log Message:
-----------
== Limit Distance Constraint ==

Added a new constraint, "Limit Distance". This constraint defines a 'virtual sphere' around the target which the owner can be made to stay inside, outside, or on the surface of it. 

This constraint is best used when applied using the Ctrl-Alt-C hotkey, as the radius is set correctly that way. 
One usage, is to prevent the target of an IK-chain from straying away from the chain. Care should be taken to not use a member of the IK-chain as the target though.

Description of Variables:
* 'Dist' - Radius of virtual sphere
* 'R' - Click on this to recalculate the 'Dist' value (note: like the 'R' button in the StretchTo constraint, this is currently buggy)
' Mode' - This menu gives different options for how the limiting sphere should act. The mode names are self explanatory.
* 'Soft' and 'SoftDistance' - currently not functional (so settings are hidden). These are used to define a smaller radius around the sphere of influence where a non-linear relationship between input and resulting locations occurs to prevent the owner 'crashing' into the sphere.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/constraint.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/include/butspace.h
    trunk/blender/source/blender/makesdna/DNA_constraint_types.h
    trunk/blender/source/blender/src/buttons_object.c
    trunk/blender/source/blender/src/editconstraint.c
    trunk/blender/source/blender/src/editipo.c

Modified: trunk/blender/source/blender/blenkernel/intern/constraint.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/constraint.c	2008-01-25 10:33:19 UTC (rev 13399)
+++ trunk/blender/source/blender/blenkernel/intern/constraint.c	2008-01-25 11:23:36 UTC (rev 13400)
@@ -2382,6 +2382,118 @@
 	locktrack_evaluate /* evaluate */
 };
 
+/* ---------- Limit Distance Constraint ----------- */
+
+static void distlimit_new_data (void *cdata)
+{
+	bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
+	
+	data->dist= 0.0;
+}
+
+static void distlimit_get_tars (bConstraint *con, ListBase *list)
+{
+	if (con && list) {
+		bDistLimitConstraint *data= con->data;
+		bConstraintTarget *ct;
+		
+		/* standard target-getting macro for single-target constraints */
+		SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+	}
+}
+
+static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+	if (con && list) {
+		bDistLimitConstraint *data= con->data;
+		bConstraintTarget *ct= list->first;
+		
+		/* the following macro is used for all standard single-target constraints */
+		SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+	}
+}
+
+static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+	bDistLimitConstraint *data= con->data;
+	bConstraintTarget *ct= targets->first;
+	
+	/* only evaluate if there is a target */
+	if (VALID_CONS_TARGET(ct)) {
+		float dvec[3], dist=0.0f, sfac=1.0f;
+		short clamp_surf= 0;
+		
+		/* calculate our current distance from the target */
+		dist= VecLenf(cob->matrix[3], ct->matrix[3]);
+		
+		/* set distance (flag is only set when user demands it) */
+		if (data->dist == 0)
+			data->dist= dist;
+		
+		/* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
+		if (data->mode == LIMITDIST_OUTSIDE) {
+			/* if inside, then move to surface */
+			if (dist <= data->dist) {
+				clamp_surf= 1;
+				sfac= data->dist / dist;
+			}
+			/* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
+			else if (data->flag & LIMITDIST_USESOFT) {
+				if (dist <= (data->dist + data->soft)) {
+					
+				}
+			}
+		}
+		else if (data->mode == LIMITDIST_INSIDE) {
+			/* if outside, then move to surface */
+			if (dist >= data->dist) {
+				clamp_surf= 1;
+				sfac= data->dist / dist;
+			}
+			/* if soft-distance is enabled, start fading once owner is dist-soft from the target */
+			else if (data->flag & LIMITDIST_USESOFT) {
+				// FIXME: there's a problem with "jumping" when this kicks in
+				if (dist >= (data->dist - data->soft)) {
+					sfac = data->soft*(1.0 - exp(-(dist - data->dist)/data->soft)) + data->dist;
+					sfac /= dist;
+					
+					clamp_surf= 1;
+				}
+			}
+		}
+		else {
+			if (IS_EQ(dist, data->dist)==0) {
+				clamp_surf= 1;
+				sfac= data->dist / dist;
+			}
+		}
+		
+		/* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
+		if (clamp_surf) {
+			/* simply interpolate along line formed by target -> owner */
+			VecLerpf(dvec, ct->matrix[3], cob->matrix[3], sfac);
+			
+			/* copy new vector onto owner */
+			VECCOPY(cob->matrix[3], dvec);
+		}
+	}
+}
+
+static bConstraintTypeInfo CTI_DISTLIMIT = {
+	CONSTRAINT_TYPE_DISTLIMIT, /* type */
+	sizeof(bDistLimitConstraint), /* size */
+	"Limit Distance", /* name */
+	"bDistLimitConstraint", /* struct name */
+	NULL, /* free data */
+	NULL, /* relink data */
+	NULL, /* copy data */
+	distlimit_new_data, /* new data */
+	distlimit_get_tars, /* get constraint targets */
+	distlimit_flush_tars, /* flush constraint targets */
+	default_get_tarmat, /* get a target matrix */
+	distlimit_evaluate /* evaluate */
+};
+
 /* ---------- Stretch To ------------ */
 
 static void stretchto_new_data (void *cdata)
@@ -3067,12 +3179,12 @@
 	constraintsTypeInfo[11]= &CTI_PYTHON;			/* Python/Script Constraint */
 	constraintsTypeInfo[12]= &CTI_ACTION;			/* Action Constraint */
 	constraintsTypeInfo[13]= &CTI_LOCKTRACK;		/* Locked-Track Constraint */
-	constraintsTypeInfo[14]= NULL;					/* 'Distance Limit' Constraint */
+	constraintsTypeInfo[14]= &CTI_DISTLIMIT;		/* Limit Distance Constraint */
 	constraintsTypeInfo[15]= &CTI_STRETCHTO; 		/* StretchTo Constaint */ 
 	constraintsTypeInfo[16]= &CTI_MINMAX;  			/* Floor Constraint */
 	constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT;	/* RigidBody Constraint */
 	constraintsTypeInfo[18]= &CTI_CLAMPTO; 			/* ClampTo Constraint */	
-	constraintsTypeInfo[19]= &CTI_TRANSFORM;		/* Transformation Constraint */	
+	constraintsTypeInfo[19]= &CTI_TRANSFORM;		/* Transformation Constraint */
 }
 
 /* This function should be used for getting the appropriate type-info when only

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2008-01-25 10:33:19 UTC (rev 13399)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2008-01-25 11:23:36 UTC (rev 13400)
@@ -1752,6 +1752,13 @@
 				data->tar = newlibadr(fd, id->lib, data->tar);
 			}
 			break;
+		case CONSTRAINT_TYPE_DISTLIMIT:
+			{
+				bDistLimitConstraint *data;
+				data= ((bDistLimitConstraint*)con->data);
+				data->tar = newlibadr(fd, id->lib, data->tar);
+			}
+			break;
 		case CONSTRAINT_TYPE_NULL:
 			break;
 		}
@@ -1765,6 +1772,7 @@
 	link_list(fd, lb);
 	for (cons=lb->first; cons; cons=cons->next) {
 		cons->data = newdataadr(fd, cons->data);
+		
 		if (cons->type == CONSTRAINT_TYPE_PYTHON) {
 			bPythonConstraint *data= cons->data;
 			link_list(fd, &data->targets);
@@ -7807,6 +7815,12 @@
 				expand_doit(fd, mainvar, data->tar);
 			}
 			break;
+		case CONSTRAINT_TYPE_DISTLIMIT:	
+			{
+				bDistLimitConstraint *data = (bDistLimitConstraint*)curcon->data;
+				expand_doit(fd, mainvar, data->tar);
+			}
+			break;
 		default:
 			break;
 		}

Modified: trunk/blender/source/blender/include/butspace.h
===================================================================
--- trunk/blender/source/blender/include/butspace.h	2008-01-25 10:33:19 UTC (rev 13399)
+++ trunk/blender/source/blender/include/butspace.h	2008-01-25 11:23:36 UTC (rev 13400)
@@ -694,7 +694,7 @@
 	B_CONSTRAINT_ADD_ACTION,
 	B_CONSTRAINT_ADD_LOCKTRACK,
 	B_CONSTRAINT_ADD_FOLLOWPATH,
-	B_CONSTRAINT_ADD_DISTANCELIMIT,
+	B_CONSTRAINT_ADD_DISTLIMIT,
 	B_CONSTRAINT_ADD_STRETCHTO,
 	B_CONSTRAINT_ADD_LOCLIMIT,
 	B_CONSTRAINT_ADD_ROTLIMIT,

Modified: trunk/blender/source/blender/makesdna/DNA_constraint_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2008-01-25 10:33:19 UTC (rev 13399)
+++ trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2008-01-25 11:23:36 UTC (rev 13400)
@@ -307,6 +307,19 @@
 	short		flag2;
 } bSizeLimitConstraint;
 
+/* Limit Distance Constraint */
+typedef struct bDistLimitConstraint {
+	Object 		*tar;
+	char 		subtarget[32];
+	
+	float 		dist;			/* distance (radius of clamping sphere) from target */
+	float		soft;			/* distance from clamping-sphere to start applying 'fade' */
+	
+	short		flag;			/* settings */
+	short 		mode;			/* how to limit in relation to clamping sphere */
+	int 		pad;
+} bDistLimitConstraint;
+
 /* ------------------------------------------ */
 
 /* bConstraint->type 
@@ -328,13 +341,14 @@
 	CONSTRAINT_TYPE_PYTHON,				/* Unimplemented no longer :) - Aligorith. Scripts */
 	CONSTRAINT_TYPE_ACTION,
 	CONSTRAINT_TYPE_LOCKTRACK,			/* New Tracking constraint that locks an axis in place - theeth */
-	CONSTRAINT_TYPE_DISTANCELIMIT,		/* was never properly coded - removed! */
+	CONSTRAINT_TYPE_DISTLIMIT,			/* limit distance */
 	CONSTRAINT_TYPE_STRETCHTO, 			/* claiming this to be mine :) is in tuhopuu bjornmose */ 
 	CONSTRAINT_TYPE_MINMAX,  			/* floor constraint */
 	CONSTRAINT_TYPE_RIGIDBODYJOINT,		/* rigidbody constraint */
 	CONSTRAINT_TYPE_CLAMPTO, 			/* clampto constraint */	
 	CONSTRAINT_TYPE_TRANSFORM,			/* transformation (loc/rot/size -> loc/rot/size) constraint */	
 	
+	
 	/* NOTE: everytime a new constraint is added, update this */
 	NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_TRANSFORM
 } B_CONSTRAINT_TYPES; 
@@ -478,6 +492,15 @@
 #define LIMIT_NOPARENT 0x01
 	/* for all Limit constraints - allow to be used during transform? */
 #define LIMIT_TRANSFORM 0x02
+
+/* distance limit constraint */
+	/* bDistLimitConstraint->flag */
+#define LIMITDIST_USESOFT		(1<<0)
+
+	/* bDistLimitConstraint->mode */
+#define LIMITDIST_INSIDE		0
+#define LIMITDIST_OUTSIDE		1
+#define LIMITDIST_ONSURFACE		2
 	
 /* python constraint -> flag */
 #define PYCON_USETARGETS	0x01

Modified: trunk/blender/source/blender/src/buttons_object.c
===================================================================
--- trunk/blender/source/blender/src/buttons_object.c	2008-01-25 10:33:19 UTC (rev 13399)
+++ trunk/blender/source/blender/src/buttons_object.c	2008-01-25 11:23:36 UTC (rev 13400)
@@ -1439,6 +1439,54 @@
 				draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
 			}
 			break;
+		case CONSTRAINT_TYPE_DISTLIMIT:
+			{
+				bDistLimitConstraint *data = con->data;
+				
+				height = 105;
+				uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+				
+				uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+				
+				/* Draw target parameters */
+				uiBlockBeginAlign(block);
+					uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
+					
+					if (is_armature_target(data->tar)) {
+						but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+						uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+					}
+					else if (is_geom_target(data->tar)) {
+						but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+						uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+					}
+					else {
+						strcpy(data->subtarget, "");
+					}
+				uiBlockEndAlign(block);
+				
+				uiBlockBeginAlign(block);
+					if (is_armature_target(data->tar)) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list