Here's another one for public discussion.
This object represents a Constraint placed on a target Vec3, usually a Point, usually Position.
The Target Vec3's value will be the averaged sum of the Input Vec3's.
Example1 : if you constrain the Position of Object A to the Position of Object B, then Object A is "glued" to Object B. This can be used to attach anything to anything else.
Example2 : if you constrain the Position of Object A to the Positions of Object B and Object C, then Object A will be forced to exist half way between Objects B and C.
This can be used to create "flocking behaviours" among troops, to simulate needs-based behaviours including fear and loathing, etc :)


MAX_CONSTRAINTS equ 4

;We want to Constrain a foreign Position to a local Position's value?
;The Target Position will be relative to one or more Sources :)
;This object should be stored in a list of some kind,
;and that list updated within the main loop.

Object PointConstraint,PointConstraintID,Primer
RedefineMethod Init
RedefineMethod Done
StaticMethod SetTargetPoint
StaticMethod AddSourceConstraintPoint,Pointer
DefineVariable pTargetPoint,Pointer,0
DefineVariable PointConstraintSourcePoints,Pointer,0
ObjectEnd

Method Done,uses esi
Destroy .PointConstraintSourcePoints
MethodEnd

Method PointConstraint.Init,uses esi
SetObject esi
mov .PointConstraintSourcePoints,$New(DwordCollection,Init,NULL,MAX_CONSTRAINTS,MAX_CONSTRAINTS,MAX_CONSTRAINTS)
MethodEnd

Method PointConstraint.AddSourceConstraintPoint,uses esi,pSourcePoint
SetObject esi
OCall .PointConstraintSourcePoints::DwordCollection.Insert,pSourcePoint
MethodEnd

;This method updates the Target Point position.
;The calculation is as follows:
;Target = (Sum of Sources) / #Sources
Method PointConstraint.Update,uses esi edi ecx
SetObject esi
xor ecx,ecx
mov ebx,.PointConstraintSourcePoints
mov edi,.pTargetPoint
fld r4_0_0f
fst .Vec3.X
fst .Vec3.Y
fstp .Vec3.Z
.while ecx<.DwordCollection.dCount
push ecx
push ebx
push edi
;Fetch ptr to Source Point
OCall ebx::DwordCollection.ItemAt,ecx
pop edi
fld .Vec3.X
fadd .Vec3.X
fstp .Vec3.X
fld .Vec3.Y
fadd .Vec3.Y
fstp .Vec3.Y
fld .Vec3.Z
fadd .Vec3.Z
fstp .Vec3.Z
pop ebx
pop ecx
inc ecx
.endw
    fld .Vec3.X
    fidiv .DwordCollection.dCount
    fstp .Vec3.X
    fld .Vec3.Y
    fidiv .DwordCollection.dCount
    fstp .Vec3.Y
    fld .Vec3.Z
    fidiv .DwordCollection.dCount
    fstp .Vec3.Z       
MethodEnd

Posted on 2005-07-17 09:34:06 by Homer
Hi Homer
The same code, a little optimized, but untested!

MAX_CONSTRAINTS equ 4

;We want to Constrain a foreign Position to a local Position's value?
;The Target Position will be relative to one or more Sources :)
;This object should be stored in a list of some kind,
;and that list updated within the main loop.

Object PointConstraint, PointConstraintID, Primer
? RedefineMethod? Init
? RedefineMethod? Done
? StaticMethod? ? SetTargetPoint
? StaticMethod? ? AddSourceConstraintPoint,? ? ?Pointer
?
? DefineVariable? pTargetPoint,? ? ? ? ? ? ? ? ?Pointer, NULL
? DefineVariable? PointConstraintSourcePoints,? Pointer, NULL
ObjectEnd

Method PointConstraint.Done
? ? SetObject ecx
? ? Destroy .PointConstraintSourcePoints
? ? ACall Done
MethodEnd

Method PointConstraint.Init, uses esi
? ? SetObject esi
? ? ACall esi.Init, NULL
? ? New DwordCollection, Init, NULL, MAX_CONSTRAINTS, MAX_CONSTRAINTS, MAX_CONSTRAINTS
? ? mov .PointConstraintSourcePoints, eax
MethodEnd

Method PointConstraint.AddSourceConstraintPoint,, pSourcePoint:Pointer
? ? SetObject ecx
? ? OCall .PointConstraintSourcePoints::DwordCollection.Insert, pSourcePoint
MethodEnd

;This method updates the Target Point position.
;The calculation is as follows:
;Target = (Sum of Sources) / #Sources
Method PointConstraint.Update, uses ebx edi esi
? ? SetObject esi
? ? fldz
? ? xor edi, edi
? ? fldz
? ? mov ebx, .PointConstraintSourcePoints
? ? fldz

? ? .while edi < .DwordCollection.dCount
? ? ? OCall ebx::DwordCollection.ItemAt, edi
? ? ? fld .Vec3.X
? ? ? faddp st(1), st(0)
? ? ? fld .Vec3.y
? ? ? faddp st(2), st(0)
? ? ? inc edi
? ? ? fld .Vec3.z
? ? ? faddp st(3), st(0)
? ? .endw
? ? fild .DwordCollection.dCount
? ? fdiv st(1), st(0)? ?
? ? fdiv st(2), st(0)? ?
? ? fdivp st(3), st(0)? ?

? ? mov edi, .pTargetPoint
? ? fstp .Vec3.X
? ? fstp .Vec3.y
? ? fstp .Vec3.z
MethodEnd


Regards,

Biterider
Posted on 2005-07-20 15:49:36 by Biterider
And a little more optimized, yet not tested :

Method PointConstraint.Update, uses ebx edi esi
    SetObject esi
    fldz
    xor edi, edi
    fldz
    mov ebx, .PointConstraintSourcePoints
    fldz
    fld1
    fidiv .DwordCollection.dCount

    .while edi < .DwordCollection.dCount
      OCall ebx::DwordCollection.ItemAt, edi
      fld .Vec3.X
      faddp st(2), st(0)
      fld .Vec3.y
      faddp st(3), st(0)
      inc edi
      fld .Vec3.z
      faddp st(4), st(0)
    .endw
    fmul st(1), st(0) 
    fmul st(2), st(0) 
    mov edi, .pTargetPoint
    fmulp st(3), st(0) 

   
    fstp .Vec3.X
    fstp .Vec3.y
    fstp .Vec3.z
MethodEnd

I think "OCall ebx::DwordCollection.ItemAt, edi"  should be replaced for further optimization
Posted on 2005-07-20 18:30:57 by Ultrano
Hi
Good idea Ultrano. Knowing that the items of any collection are stored in a linear memory block without gaps, the code can be rewritten as follows:

Method PointConstraint.Update, uses ebx edi esi
    SetObject esi
    fldz
    xor edi, edi
    fldz
    mov ebx, .PointConstraintSourcePoints
    fldz
    fld1
    fidiv .DwordCollection.dCount

    lea eax, .DwordCollection.pItems
    .while edi < .DwordCollection.dCount
      fld .Vec3.x
      faddp st(2), st(0)
      fld .Vec3.y
      faddp st(3), st(0)
      inc edi
      fld .Vec3.z
      add eax, 4
      faddp st(4), st(0)
    .endw
    fmul st(1), st(0) 
    fmul st(2), st(0) 
    mov edi, .pTargetPoint
    fmulp st(3), st(0) 
   
    fstp .Vec3.x
    fstp .Vec3.y
    fstp .Vec3.z
MethodEnd


Biterider
Posted on 2005-07-21 00:17:00 by Biterider
Good stuff :)
I'd like to expand this topic to cover more complex constraints shortly, and I've found precious little information regarding implementations :(

I'm interested particularly in Joint Constraints, including but not limited to the following:
-Simple Rotation Constraints, including nDOF joints such as Ball and Hinge
-Complex Rotation Constraints, including Aim (orientation) Constraint
-Non-Commutative association constraints, eg, rotation of jetplane landing gear is constrained to the 3D Y position of the jetplane, so it automatically retracts on takeoff, etc.


Do you think I'm handling N-source point constraints correctly?
Am I doing it backwards?
Posted on 2005-07-21 00:33:21 by Homer
Non-commutative constraints require a Type field.
The constraint needs to know the following information regarding Source and Target objects:
-constrainor data type
-constrainor data range
-constrainee data type
-constrainee data range

Let's go with the example I gave in the previous post.
We have some landing gear on a jetplane.
Let's keep it simple.
Let's assume that this Constraint can only have a single Source of known Type.
Let's assume theres a single axial hinged joint to extend and retract the landing gear
Let's assume that at 0 degrees, it's fully retracted, and at 120 degrees, its fully extended.
Now for that Y constraint.
Let's assume that at Y=5, the jetplane is on the runway, its landing gear at 120 degrees.
Furthermore, that at Y=20+, the landing gear is at 0 degrees.
We are constraining a float to another float here, it's not too hard to implement..
We can get away with simple interpolation, if we apply the LIMITS first.
If Y<YMin, Y=YMin
If Y>YMax, Y=YMax
Now we can calculate the "completion ratio" of current Y value, and apply it to the Angular Range to produce a value that is rationally equivalent.
How would YOU do it?
Posted on 2005-07-21 00:55:06 by Homer