RE: stick based goal with weight map

Date : Mon, 24 Apr 2006 19:43:36 -0400
To : <XSI(at)Softimage.COM>
From : "Sebastien Nadeau" <sebastien.nadeau(at)ubisoft.com>
Subject : RE: stick based goal with weight map
I came across the same problem 2 weeks ago... Well I didn't find any
nice way of doing it but I wrote a 
small scripted Event that stores in a UserDataBlob the coordinates at
which a particle is being emmited,
and than read the values and store it in the  Goal_0_UVWI  parameter for
the goal.

It gets slow with a lot of particle, but you could start from that
exemple and modify it to suit your need..

Hope this helps...

here is a small exemple scene of what I did.. just run it in a new scene
and you will see what it does.

//------------START-------------//

//Stick_Emission_01.js
//By Sebastien Nadeau
//Description:

//--------------
//USER PARAM
var nbParticle = 100000;
var poffset = 0.1;
//--------------



Main();

function Main()
{
	//Create Sphere
	var EmmiterGoal = CreatePrim("Sphere", "MeshSurface", null,
null);
	ApplyTopoOp("TriangulatePolygons", EmmiterGoal, siUnspecified,
siPersistentOperation, null);
	FreezeModeling(EmmiterGoal, null, null);
	
	//Create WeigthMap
	var WeightMap = CreateWM(EmmiterGoal);
	
	//Create Particle
	var Cloud = CreateParticleCloud(EmmiterGoal, "")(0);
	
	//Find Ptype and Emission
	var CloudOp =
Cloud.ActivePrimitive.NestedObjects("ParticlesOp");
	for ( var i=0; i<CloudOp.InputPorts.Count; i++ ){
		if(CloudOp.InputPorts(i).Target2.type == "ParType")
			var pType = CloudOp.InputPorts(i).Target2;
		if(CloudOp.InputPorts(i).Target2.type == "EmissionProp")
			var EmissionProp= CloudOp.InputPorts(i).Target2;
	}
 	
	//Setup Goal
	var Goal = AddParticleGoal(pType , EmmiterGoal, null)(1)(0);
		//Stick
		Goal.Parameters("Behavior").Value = 4;

	//Set Emission
	EmissionProp.Parameters("Rate").value = nbParticle;
	ApplyOp("MapCompOp2",
WeightMap+";"+EmissionProp.Parameters("Rate"), null, null, null, 0);
	
	//Set Other Param
	pType.Parameters("LiveForever").Value = true;
	pType.Parameters("AlignOnVelocity").Value = true;
	
	//Event
	var PEvent = AddParticleEvent(pType, "", null)(0)(0);
	PEvent.Parameters("EventTrigger").Value = 2;
	PEvent.Parameters("TriggerValue").Value = 1;
	PEvent.Parameters("EventAction").Value = 6;
	PEvent.Parameters("ScriptLanguage").Value = 1;
	PEvent.Parameters("ScriptContext").Value = 2;
	
	//Offset Emission Animation
	var oPlayCrtl = Dictionary.GetObject( "PlayControl" );
	SetKey(EmissionProp.Parameters("Mute"),
oPlayCrtl.Parameters("Out").value - 1, false, null);
	SetKey(EmissionProp.Parameters("Mute"),
oPlayCrtl.Parameters("Out").value, true, null);
	SetKey(PEvent.Parameters("Mute"),
oPlayCrtl.Parameters("Out").value - 1, false, null);
	SetKey(PEvent.Parameters("Mute"),
oPlayCrtl.Parameters("Out").value, true, null);
	//Offset Particle Simulation
	CloudOp.Parameters("Offset").Value =
oPlayCrtl.Parameters("Out").value - 1;
		
	//Create UserDataBlob Properties to save Arrays
	Cloud.AddProperty( "UserDataBlob", false, "Distribution" );
	
	//Set Temp Event Script to store the Goal values in the
UserDataBlob
	PEvent.Parameters("Script").Value = "var aDistrib = new
Array();\r\n\r\nfor ( var i=0; i<inParticleCloud.Particles.Count; i++
)\r\n {\r\n\tvar inParticle = inParticleCloud.Particles(i);\r\n\r\n//Get
UVWI\r\n\tvar q =
inParticle.Attributes(\"Goal_0_UVWI\").Value;\r\n\r\n//Particle
position\r\n\tvar v2 = XSIMath.CreateVector3();\r\n\tv2 =
inParticle.Position;\r\n\r\n//Point Locator\r\n\tvar EmitGeo =
Dictionary.GetObject(\""+EmmiterGoal.FullName+"\").ActivePrimitive.Geome
try;\r\n\tvar ClosestPointLocator =
EmitGeo.GetClosestLocations(VBArray(v2.Get2()).toArray());\r\n\r\n//Get
Triangle and Coordinate\r\n\tvar Poly  =
EmitGeo.GetPolygonIndexArray(ClosestPointLocator).toArray();\r\n\tvar
BaryCoords =
EmitGeo.GetTriangleWeightArray(ClosestPointLocator).toArray();\r\n\tq.Se
t (Poly[0], BaryCoords[0], BaryCoords[2] , q(3))\r\n\r\n//Get Closest
point to Mesh\r\n\tvar v1 = XSIMath.CreateVector3();\r\n\tvar Cp =
EmitGeo.EvaluatePositions(ClosestPointLocator).toArray();\r\n\tv1.Set(
Cp[0], Cp[1], Cp[2]);\r\n\t\r\n//Get
Orientation\r\n\tv2.SubInPlace(v1);\r\n\tv2.NormalizeInPlace();\r\n\tv2.
ScaleInPlace("+poffset+");\r\n\r\n//Set the
offset\r\n\tinParticle.Attributes(\"Goal_0_Offset\").Value =
v2;\r\n\t\r\n//Set new
Index\r\n\tinParticle.Attributes(\"Goal_0_UVWI\").Value =
q;\r\n\t\t\r\n//Set UserDataBlob\r\n\taDistrib.push(v2.X, v2.Y,
v2.Z);\r\n\taDistrib.push(q.W, q.X, q.Y,
q.Z);\r\n}\r\nDictionary.GetObject(\""+Cloud.FullName+"\").Properties(\"
Distribution\").Value = aDistrib;";
	//Go to Last Frame
	LastFrame();
	refresh();
 



//-----------------COMMENT THE REST TO STUDY THE FIRST PART OF THE
SCRIPT---------------------------//

	//Set Event Script that will read the UserDataBlob at the first
frame
	PEvent.Parameters("Script").Value = "var aDistrib =
Dictionary.GetObject(\""+Cloud.FullName+"\").Properties(\"Distribution\"
).Value.split(\",\");\r\n\r\nfor ( var i=0; i <
(inParticleCloud.Particles.Count * 7); i += 7 )\r\n{\r\n\tvar inParticle
= inParticleCloud.Particles(i/7);\r\n//Set the offset\r\n\tvar v1 =
XSIMath.CreateVector3();\r\n\tv1.Set(aDistrib[i], aDistrib[i+1],
aDistrib[i+2]);\r\n\tinParticle.Attributes(\"Goal_0_Offset\").Value =
v1;\r\n\r\n//Set new Index\r\n\tvar q =
XSIMath.CreateQuaternion();\r\n\tq.Set(aDistrib[i+3], aDistrib[i+4],
aDistrib[i+5],
aDistrib[i+6]);\r\n\tinParticle.Attributes(\"Goal_0_UVWI\").Value
=q;\r\n\r\n}";

	//Reset Offset
		CloudOp.Parameters("Offset").Value =
oPlayCrtl.Parameters("In").value;	
	//Animate Emission
		RemoveAnimation(EmissionProp.Parameters("Mute"), 0,
null);
		RemoveAnimation(PEvent.Parameters("Mute"), 0, null);
		SetKey(EmissionProp.Parameters("Mute"),
oPlayCrtl.Parameters("In").value, false, null);
		SetKey(EmissionProp.Parameters("Mute"),
oPlayCrtl.Parameters("In").value + 1, true, null);
		SetKey(PEvent.Parameters("Mute"),
oPlayCrtl.Parameters("In").value, false, null);
		SetKey(PEvent.Parameters("Mute"),
oPlayCrtl.Parameters("In").value + 1, true, null);
	//Go Back to First Frame
		FirstFrame();

//-----------------------------------------------//


}

function CreateWM(oObj)
{
	var WM = CreateWeightMap(null, oObj, "Weight_Map", null,
null)(0);
	var Weights = VBArray(WM.Elements.Array).toArray();

	var Points = oObj.ActivePrimitive.Geometry.Points;
	var p1 = oObj.ActivePrimitive.Geometry.Points(0).Position;
	
	var vdist = XSIMath.CreateVector3();
	var maxDist = 0;
	for(var j = 0; j < Points.Count;j++)
	{
		vdist.Sub(p1, Points(j).Position);
		Weights[j] = vdist.Length();
		
		if(Math.random() < 0.8)
			Weights[j] = 0; 
		
		if(Weights[j] > maxDist)
			maxDist = Weights[j]; 
	}
	for(var k = 0; k < Points.Count; k++)
		Weights[k] = (Weights[k] / maxDist);
		
	WM.Elements.Array = Weights;
	
	return WM;
}


//------------END-------------// 
 
-----Original Message-----
From: owner-xsi(at)Softimage.COM [mailto:owner-xsi(at)Softimage.COM] On Behalf
Of Kris Rivel
Sent: Monday, April 24, 2006 6:25 PM
To: XSI List Server
Subject: stick based goal with weight map

Is there a way to have particles stick to a weight map or texture map?  
I need to generate some particles that are on a mesh as the mesh moves 
around.  The "stick" goal simply overrides any weight map you emit from 
resulting in the particles being evenly scattered on the surface.

Kris

---
Unsubscribe? Mail Majordomo(at)Softimage.COM with the following text in
body:
unsubscribe xsi

---
Unsubscribe? Mail Majordomo(at)Softimage.COM with the following text in body:
unsubscribe xsi


Search the XSI List archives here or use the advanced search form to search across mailing lists. Searching help is available.
This site supposedly brought to you by Benjamin Grosser and the Imaging Technology Group.