Awesome stuff rumblesushi (and keen awesome as always ).
How does the system grid work? Does it generate an Id for every object and checks in into the field by position (like distance to left border divided by field width multiplied with width of a single box?). Would really appreciate a write down on your method there.
Oh, the extra 1 (361, 1001) is actually the debug grid itself, a 5000 triangle plane.
e-freak - Finding which grid node you're on is ridiculously simple, that's one of the reasons I like grids.
You already have the grid segment size (gridSize / gridSegments) - so you simply find out which column and row you're on like this, making sure col and row are integers obviously -
Then once you know the current column and row any given object is on, you know the exact grid node, and can access it easily in a 2D or 1D array, as you know it's index.
Oh and of course if you have a 3D grid, you'd need to do the same thing in the y axis.
One of the reasons this grid is so fast, is I am not iterating through the grid. It's managed by the moving objects, they add/remove themselves and check for collisions. So that means I could have a huge grid with say 200,000 nodes running at the exact same speed as this one, because the amount of look ups and collisions etc would be the same.
Now I just have to develop a fast, solid per polygon collision routine (for the floors/walls etc of a level) and I can start making my first game. I can use this grid and a 3D version of this grid as a broad phase obviously, but I need to work on the actual polygon collision resolvement, colliding with multiple polygons etc.
Though this is just a tech demo, I'd like to make a fast, furious, stylised 3D shooter with similar visuals to this demo (but better/more developed obviously). Do you prefer the default flat shaded floor, or the Geometry Wars style pure wireframe after pressing R?
Playing around in UT2004 again, plan to make a bigger version, more spinners, maybe code it to do it based on team for ONS/DDOM gametypes so it'll spin to show the team icon when a node is captured or a controlpoint is touched.
try it with your own mug (yes you need a webcam to test it): http://renderhjs.net/_tmp/soap/tracking.swf
use spacebar to swap the decoration on your face, d -key to swap the debug rendering.
its missing some of the interpolation stuff right now which makes it more smooth and natural as it dances and shakes at times but I am already quite pleased with the recognition rate (all based on that grey scale video input)
i used a cheap trick last time i worked on webcam tracking (color tracking) (not sure if it's applicable or you might come up with a better solution):
- Taking the average position of the tracker in the (up to) last 10 frames.
-- This smoothes out all jumping but it gives a slight lag (if you move your head too fast).
- So instead of taking the full number of frames you compare the last values
-- try to produce the average increase of values (linear function) in these last (ten) values
--- if none of the values "jump" (leaves the linear function from more than a tolerance value)
---- reduce the frames to three (still smoothes out the movement but is not noticable lag)
you can make the number of smoothing frames used change dynamically based on the difference from the linear function.
I got the go ahead from a candian chap who was the original creator of the 3ch topic generator to reinterpret his work.
Anyway I've been fucking my mind with allsorts of complicated stuff which is probably piss-easy to an actual programmer, but it's more fun than sudoku, right?
So I remade it. Now accepts neater file format, still pretty simple, allows multiple 'structures' to be composited together, recursively (so it is easy to break if you make a rubbish datase with infinite recursion in it) - I will add some checks to stop it going on forever next time i'm in the rat's maze looking at its glutionous underbelly.
Anyway, a bit of fun, and I think it is something I always wanted, which is as good a motivation as any to make a tool, am I right?
this question probably doesn't fit this thread too well, but I don't think it justifies a new thread.
Does anyone know of a script that aligns an object to another based on their selected vertices?
In the example above I know that the two selected vertices on the light grey object should be on the same positions as the two vertices on the dark grey object.
Now, if there was a script that rotates, scales and moves the light grey object in a way that the vertices are on the same position as on the other object, we wouldn't have to go through the process of align everything by hand, which probably would takes ages.
Started messing around with shaderfx; my try at a dry + damp + puddle material controlled by vertex painting. Inspired by the screens of Ryan James Smith's UDK advanced mesh paint material seen here: http://www.3dmotive.com/product-udk-mesh-paint
So I assume the water moves cause my squinty eyes see a time node and normal panning I was planning on looking into water animation when I get around to doing Virtuosic's tutorial. Just watched it on the bus and never got around to actually making it,
YAY it works. My first script, well not done yet. Need to figure out how to save a query to a vector variable then Ill be golden
EDIT: Guess I should say what the script does haha. Well I do a lot of props modeling within the same scene file and just throw them around the level but if I ever want to use the prop again the pivot point is like way over there. So this puts the pivot in the center if it was moved, freezes transformations, querys world space of the pivot and moves it to 0,0,0. The xform query x etc is just placeholder and does not actually work. need to figure out how to save that to a variable and then gonna work on a UI. Also gonna include a batch FBX (profile for Unreal)/obj exporter in there and possibility of tweaking your pivot after its at 0,0,0
EDIT: Also grabbed a video of diffuse shader next up Spec, Normal and ambient color.
one way to use mr's roundcorners node to get beveled edges in normal maps without modeling them. also chamfers where geometry intersects:)
if anyone knows how to convert world space to tangent space using default maya nodes, that would be more ideal then using xNormal in this process, nothing against xNormal, just an extra step here that I'm sure can be cut out.
I was actually reading those before, funny how small a world sometimes appears. They have a nice writeup and definitely should be shared more frequently among resource spots and people that want to learn max in more depth.
I fixed up my shader editor to work with unity3. This example shows "alpha to coverage" or whatever its called. I made a special node to do this, but it could also be done by assembling other nodes together.
Took the xyzWindow script for Maya posted here the other day and updated it to be a full transform type-in window that mimics Max. Maybe someone here can get some use out of it (or give some thoughts on improving it):
//////////////////////////////////////////////////
//title: xyzWindow
//Version: 2.0
//Date: Aug/05/2010
//Tested under: Maya 2009
//created by: Polyhertz (polyhertz3d.com)
//Features:
// -Get selection center coordinates based on bounding box for components and pivots for objects
// -Move/rotate/scale objects as a group based on averaged pivot center
// -Move objects or components in absolute values while retaining groups relative offset from each other
// -Rotate/Scale seperately
//known limitations:
// -Move in absolute values doesnt work properly with non-world axis.
// -Doesnt work in pivot edit mode. If someone knows how to find out when the user is in this mode let me know and ill add it.
// -Only updates when tool mode / selection is updated/changed, or undo is used. Due to limited useful scriptjob events.
// -Object/world/local only supported axis's
// -Scale field 1 scales to world xyz 0 on components. What should I have it do instead, suggestions?
//////////////////////////////////////////////////
//windowPref -ra;
//---------------------Window Start---------------------
if (`window -exists xyzWindow`) {deleteUI xyzWindow;}
window -wh 255 115 -mxb 0 -title "xyzWindow: component positions" xyzWindow;
formLayout -h 100 colLay;
frameLayout -bs "etchedOut" -w 110 -l "Absolute:World" -lw 105 -p colLay frmOne;
rowColumnLayout -numberOfColumns 2 -columnAttach 1 "right" 0 -columnWidth 1 20 -columnWidth 2 90 -p frmOne;
text -label "X:";
global string $Xtf;
$Xtf = `textField`;
text -label "Y:";
global string $Ytf;
$Ytf = `textField`;
text -label "Z:";
global string $Ztf;
$Ztf = `textField`;
frameLayout -bs "etchedOut" -w 110 -l "Offset:World" -lw 105 -p colLay frmTwo;
rowColumnLayout -numberOfColumns 2 -columnAttach 1 "right" 0 -columnWidth 1 20 -columnWidth 2 90 -p frmTwo;
text -label "X:";
global string $Xtf2;
$Xtf2 = `textField`;
text -label "Y:";
global string $Ytf2;
$Ytf2 = `textField`;
text -label "Z:";
global string $Ztf2;
$Ztf2 = `textField`;
formLayout -edit
-af frmOne left 5
-ac frmTwo left 5 frmOne
colLay;
textField -edit -aie 1 -ec entProcOne $Xtf;
textField -edit -aie 1 -ec entProcOne $Ytf;
textField -edit -aie 1 -ec entProcOne $Ztf;
textField -edit -aie 1 -ec entProcTwo $Xtf2;
textField -edit -aie 1 -ec entProcTwo $Ytf2;
textField -edit -aie 1 -ec entProcTwo $Ztf2;
showWindow xyzWindow;
//---------------------Startup---------------------
scriptJob -parent xyzWindow -e SelectionChanged maniProc;
scriptJob -parent xyzWindow -e ToolChanged maniProc;
scriptJob -parent xyzWindow -e Undo maniProc;
maniProc;
//---------------------Input Tasks---------------------
global proc entProcOne () //do everytim user enters new value in first set of textfields
{
if ((`currentCtx`) == "moveSuperContext") {entMoveProcOne;}
if ((`currentCtx`) == "RotateSuperContext") {entRotateProcOne;}
if ((`currentCtx`) == "scaleSuperContext") {entScaleProcOne;}
}
global proc entProcTwo () //do everytim user enters new value in second set of textfields
{
if ((`currentCtx`) == "moveSuperContext") {entMoveProcTwo;}
if ((`currentCtx`) == "RotateSuperContext") {entRotateProcTwo;}
if ((`currentCtx`) == "scaleSuperContext") {entScaleProcTwo;}
}
//---------------------Field display---------------------
global proc maniProc () //do everytime manipulator or selection changes
{
global string $Xtf, $Ytf, $Ztf, $Xtf2, $Ytf2, $Ztf2;
AvgSelProc; //update stored selection average
if ((`currentCtx`) == "selectSuperContext")
{
window -edit -title "xyz positions" xyzWindow;
frameLayout -edit -l "Offset:World" frmOne;
frameLayout -edit -l "Offset:World" frmTwo;
}
if ((`currentCtx`) == "moveSuperContext")
{
window -edit -title "Move xyz positions" xyzWindow;
frameLayout -edit -l "Offset:World" frmOne;
frameLayout -edit -l "Offset:World" frmTwo;
}
if ((`currentCtx`) == "RotateSuperContext")
{
window -edit -title "Rotate xyz positions" xyzWindow;
frameLayout -edit -l "Rotate:Separate" frmOne;
frameLayout -edit -l "Rotate:Together" frmTwo;
}
if ((`currentCtx`) == "scaleSuperContext")
{
window -edit -title "Scale xyz positions" xyzWindow;
frameLayout -edit -l "Scale:Separate" frmOne;
frameLayout -edit -l "Scale:Together" frmTwo;
}
if ((`currentCtx`) == "selectSuperContext" || (size(`ls -sl -fl`)) == 0)
{
textField -edit -en 0 $Xtf;
textField -edit -en 0 $Ytf;
textField -edit -en 0 $Ztf;
textField -edit -en 0 $Xtf2;
textField -edit -en 0 $Ytf2;
textField -edit -en 0 $Ztf2;
textField -edit -tx ("0.0") $Xtf;
textField -edit -tx ("0.0") $Ytf;
textField -edit -tx ("0.0") $Ztf;
textField -edit -tx ("0.0") $Xtf2;
textField -edit -tx ("0.0") $Ytf2;
textField -edit -tx ("0.0") $Ztf2;
}
if ((`currentCtx`) != "selectSuperContext" && (size(`ls -sl -fl`)) >= 1)
{
textField -edit -en 1 $Xtf;
textField -edit -en 1 $Ytf;
textField -edit -en 1 $Ztf;
textField -edit -en 1 $Xtf2;
textField -edit -en 1 $Ytf2;
textField -edit -en 1 $Ztf2;
}
if ((`currentCtx`) == "moveSuperContext" && (size(`ls -sl -fl`)) >= 1)
{
textField -edit -tx ("0.0") $Xtf2;
textField -edit -tx ("0.0") $Ytf2;
textField -edit -tx ("0.0") $Ztf2;
}
if ((`currentCtx`) == "RotateSuperContext" && (size(`ls -sl -fl`)) >= 1)
{
rotAngleProc;
textField -edit -tx ("0.0") $Xtf2;
textField -edit -tx ("0.0") $Ytf2;
textField -edit -tx ("0.0") $Ztf2;
}
if ((`currentCtx`) == "scaleSuperContext" && (size(`ls -sl -fl`)) >= 1)
{
textField -edit -tx ("1.0") $Xtf;
textField -edit -tx ("1.0") $Ytf;
textField -edit -tx ("1.0") $Ztf;
textField -edit -tx ("1.0") $Xtf2;
textField -edit -tx ("1.0") $Ytf2;
textField -edit -tx ("1.0") $Ztf2;
}
}
//---------------------Averages Selection Positon---------------------
global proc AvgSelProc () //gets the average of selection, and updates textfields
{
global string $Xtf, $Ytf, $Ztf;
global float $holdAvgX, $holdAvgY, $holdAvgZ;
float $Xpos, $Ypos, $Zpos;
$selectComp = `ls -sl -fl`;
if ((`size $selectComp`) == 0)
{
textField -edit -tx ("") $Xtf;
textField -edit -tx ("") $Ytf;
textField -edit -tx ("") $Ztf;
}
if ((`size $selectComp`) >= 1 && (`selectMode -q -o`) == 0)
{
string $tool = `currentCtx`;
setToolTo moveSuperContext;
vector $Pos = `manipMoveContext -q -p Move`;
setToolTo $tool;
textField -edit -tx ($Pos.x) $Xtf;
textField -edit -tx ($Pos.y) $Ytf;
textField -edit -tx ($Pos.z) $Ztf;
$holdAvgX = `textField -q -tx $Xtf`;
$holdAvgY = `textField -q -tx $Ytf`;
$holdAvgZ = `textField -q -tx $Ztf`;
}
if ((`size $selectComp`) >= 1 && (`selectMode -q -o`) == 1)
{
for ($each in $selectComp)
{
$Pos = `xform -q -ws -t $each`;
$Xpos = $Pos[0] + $Xpos;
$Ypos = $Pos[1] + $Ypos;
$Zpos = $Pos[2] + $Zpos;
}
$Xpos = ($Xpos / (`size $selectComp`));
$Ypos = ($Ypos / (`size $selectComp`));
$Zpos = ($Zpos / (`size $selectComp`));
//Deals with exponential numbers
if ($Xpos < 0.000001 && $Xpos > -0.000001) {$Xpos = 0;}
if ($Ypos < 0.000001 && $Ypos > -0.000001) {$Ypos = 0;}
if ($Zpos < 0.000001 && $Zpos > -0.000001) {$Zpos = 0;}
textField -edit -tx $Xpos $Xtf;
textField -edit -tx $Ypos $Ytf;
textField -edit -tx $Zpos $Ztf;
$holdAvgX = `textField -q -tx $Xtf`;
$holdAvgY = `textField -q -tx $Ytf`;
$holdAvgZ = `textField -q -tx $Ztf`;
}
}
//---------------------Current Rotation Angle Average---------------------
global proc rotAngleProc ()
{
global string $Xtf, $Ytf, $Ztf;
global float $holdRotX, $holdRotY, $holdRotZ;
$selectComp = `ls -sl -fl`;
float $rotX, $rotY, $rotZ;
if ((`manipRotateContext -q -m Rotate`) == 0) //Object/Local space
{
for ($each in $selectComp)
{
$rotationVar = `xform -q -ro $each`;
$rotX = ($rotX + $rotationVar[0]);
$rotY = ($rotY + $rotationVar[1]);
$rotZ = ($rotZ + $rotationVar[2]);
}
$rotX = ($rotX / (size ($selectComp)));
$rotY = ($rotY / (size ($selectComp)));
$rotZ = ($rotZ / (size ($selectComp)));
//Deals with exponential numbers
if ($rotX < 0.000001 && $rotX > -0.000001) {$rotX = 0;}
if ($rotY < 0.000001 && $rotY > -0.000001) {$rotY = 0;}
if ($rotZ < 0.000001 && $rotZ > -0.000001) {$rotZ = 0;}
textField -edit -tx $rotX $Xtf;
textField -edit -tx $rotY $Ytf;
textField -edit -tx $rotZ $Ztf;
$holdRotX = `textField -q -tx $Xtf`;
$holdRotY = `textField -q -tx $Ytf`;
$holdRotZ = `textField -q -tx $Ztf`;
}
if ((`manipRotateContext -q -m Rotate`) == 1) //world space
{
textField -edit -tx ("0.0") $Xtf;
textField -edit -tx ("0.0") $Ytf;
textField -edit -tx ("0.0") $Ztf;
}
}
//---------------------Move Input - Field Column 1---------------------
global proc entMoveProcOne ()
{
global string $Xtf, $Ytf, $Ztf;
global float $holdAvgX, $holdAvgY, $holdAvgZ;
float $xFieldTXT = `textField -q -tx $Xtf`;
float $yFieldTXT = `textField -q -tx $Ytf`;
float $zFieldTXT = `textField -q -tx $Ztf`;
$selectComp = `ls -sl -fl`;
$manipAxis = `manipMoveContext -q -m Move`;
if ((`size $selectComp`) >= 1)
{
//X functions
if ($holdAvgX > $xFieldTXT)
{
$difX = ($holdAvgX - $xFieldTXT); //dif as pos
$difX = ($difX * -1);
if ($manipAxis == 0) {move -r -os $difX 0 0;} //object space
if ($manipAxis == 1) {move -r -ls $difX 0 0;} //world space
if ($manipAxis == 2) {move -r -ws $difX 0 0;} //local space
}
if ($holdAvgX < $xFieldTXT)
{
$difX = ($xFieldTXT - $holdAvgX); //dif as pos
if ($manipAxis == 0) {move -r -os $difX 0 0;} //object space
if ($manipAxis == 1) {move -r -ls $difX 0 0;} //world space
if ($manipAxis == 2) {move -r -ws $difX 0 0;} //local space
}
//Y functions
if ($holdAvgY > $yFieldTXT)
{
$difY = ($holdAvgY - $yFieldTXT); //dif as pos
$difY = ($difY * -1);
if ($manipAxis == 0) {move -r -os 0 $difY 0;} //object space
if ($manipAxis == 1) {move -r -ls 0 $difY 0;} //world space
if ($manipAxis == 2) {move -r -ws 0 $difY 0;} //local space
}
if ($holdAvgY < $yFieldTXT)
{
$difY = ($yFieldTXT - $holdAvgY); //dif as pos
if ($manipAxis == 0) {move -r -os 0 $difY 0;} //object space
if ($manipAxis == 1) {move -r -ls 0 $difY 0;} //world space
if ($manipAxis == 2) {move -r -ws 0 $difY 0;} //local space
}
//Z functions
if ($holdAvgZ > $zFieldTXT)
{
$difZ = ($holdAvgZ - $zFieldTXT); //dif as pos
$difZ = ($difZ * -1);
if ($manipAxis == 0) {move -r -os 0 0 $difZ;} //object space
if ($manipAxis == 1) {move -r -ls 0 0 $difZ;} //world space
if ($manipAxis == 2) {move -r -ws 0 0 $difZ;} //local space
}
if ($holdAvgZ < $zFieldTXT)
{
$difZ = ($zFieldTXT - $holdAvgZ); //dif as pos
if ($manipAxis == 0) {move -r -os 0 0 $difZ;} //object space
if ($manipAxis == 1) {move -r -ls 0 0 $difZ;} //world space
if ($manipAxis == 2) {move -r -ws 0 0 $difZ;} //local space
}
AvgSelProc;
}
}
//---------------------Move Input - Field Column 2---------------------
global proc entMoveProcTwo ()
{
global string $Xtf2, $Ytf2, $Ztf2;
float $xFieldTXT = `textField -q -tx $Xtf2`;
float $yFieldTXT = `textField -q -tx $Ytf2`;
float $zFieldTXT = `textField -q -tx $Ztf2`;
if ((`manipMoveContext -q -m Move`) == 0) {move -r -os $xFieldTXT $yFieldTXT $zFieldTXT;} //object space
if ((`manipMoveContext -q -m Move`) == 1) {move -r -ls $xFieldTXT $yFieldTXT $zFieldTXT;} //world space
if ((`manipMoveContext -q -m Move`) == 2) {move -r -ws $xFieldTXT $yFieldTXT $zFieldTXT;} //local space
textField -edit -tx ("0.0") $Xtf2;
textField -edit -tx ("0.0") $Ytf2;
textField -edit -tx ("0.0") $Ztf2;
AvgSelProc;
}
//---------------------Rotate Input - Field Column 1---------------------
global proc entRotateProcOne ()
{
global string $Xtf, $Ytf, $Ztf;
global float $holdRotX, $holdRotY, $holdRotZ;
float $xFieldTXT = `textField -q -tx $Xtf`;
float $yFieldTXT = `textField -q -tx $Ytf`;
float $zFieldTXT = `textField -q -tx $Ztf`;
$selectComp = `ls -sl -fl`;
if ((`size $selectComp`) >= 1)
{
//X functions
if ($holdRotX > $xFieldTXT)
{
$difX = ($holdRotX - $xFieldTXT); //dif as pos
$difX = ($difX * -1);
rotate -r -os $difX 0 0;
}
if ($holdRotX < $xFieldTXT)
{
$difX = ($xFieldTXT - $holdRotX); //dif as pos
rotate -r -os $difX 0 0;
}
//Y functions
if ($holdRotY > $yFieldTXT)
{
$difY = ($holdRotY - $yFieldTXT); //dif as pos
$difY = ($difY * -1);
rotate -r -os 0 $difY 0;
}
if ($holdRotY < $yFieldTXT)
{
$difY = ($yFieldTXT - $holdRotY); //dif as pos
rotate -r -os 0 $difY 0;
}
//Z functions
if ($holdRotZ > $zFieldTXT)
{
$difZ = ($holdRotZ - $zFieldTXT); //dif as pos
$difZ = ($difZ * -1);
rotate -r -os 0 0 $difZ;
}
if ($holdRotZ < $zFieldTXT)
{
$difZ = ($zFieldTXT - $holdRotZ); //dif as pos
rotate -r -os 0 0 $difZ;
}
}
}
//---------------------Rotate Input - Field Column 2---------------------
global proc entRotateProcTwo ()
{
global string $Xtf2, $Ytf2, $Ztf2;
global float $holdAvgX, $holdAvgY, $holdAvgZ;
float $xFieldTXT = `textField -q -tx $Xtf2`;
float $yFieldTXT = `textField -q -tx $Ytf2`;
float $zFieldTXT = `textField -q -tx $Ztf2`;
rotate -r -p $holdAvgX $holdAvgY $holdAvgZ -ocp $xFieldTXT $yFieldTXT $zFieldTXT;
textField -edit -tx ("0.0") $Xtf2;
textField -edit -tx ("0.0") $Ytf2;
textField -edit -tx ("0.0") $Ztf2;
}
//---------------------Scale Input - Field Column 1---------------------
global proc entScaleProcOne ()
{
global string $Xtf, $Ytf, $Ztf;
global float $holdAvgX, $holdAvgY, $holdAvgZ;
float $xFieldTXT = `textField -q -tx $Xtf`;
float $yFieldTXT = `textField -q -tx $Ytf`;
float $zFieldTXT = `textField -q -tx $Ztf`;
scale -r $xFieldTXT $yFieldTXT $zFieldTXT;
textField -edit -tx ("1.0") $Xtf;
textField -edit -tx ("1.0") $Ytf;
textField -edit -tx ("1.0") $Ztf;
}
//---------------------Scale Input - Field Column 2---------------------
global proc entScaleProcTwo ()
{
global string $Xtf2, $Ytf2, $Ztf2;
global float $holdAvgX, $holdAvgY, $holdAvgZ;
float $xFieldTXT = `textField -q -tx $Xtf2`;
float $yFieldTXT = `textField -q -tx $Ytf2`;
float $zFieldTXT = `textField -q -tx $Ztf2`;
scale -r -p $holdAvgX $holdAvgY $holdAvgZ $xFieldTXT $yFieldTXT $zFieldTXT;
textField -edit -tx ("1.0") $Xtf2;
textField -edit -tx ("1.0") $Ytf2;
textField -edit -tx ("1.0") $Ztf2;
}
@Polyhertz: Wow 2011 is freaking out. First ran it no problems but gave me errors about -lw flag and saying it was obsolete. Now just says syntax error Is there anyway to update on the fly (like when moving the vert by the pivot point?) cause I have to switch to another tool then switch back to refresh the text box.
Maya 2011 breaks several commands, such as selectMode and selectType, which are very important for determining what mode the user is in. Frame sizes dont work the same either (so stuff gets cut off). I need to check and and see if they've got replacements for some commands to make a 2011 specific version.
As for auto-refreshing, actually if you click on the tool your already in (like if your in move press W) it'll refresh too. Right now it's using scriptjobs to update when certain events happen, but exposed events are limited. I'd imagine their's a way to do it through the API (so as a plugin), but havn't really delved into that.
Been playing Mount & Blade Warband recently, and decided to have a crack at learning Python properly by writing an importer for their binary BRF format.
Been reverse-engineering the format based on their export script for Python, mostly pretty straightforward so far.
Currently I'm just building the raw mesh, next up is applying the specific vertex data like UVs, normals, tangents etc.
After that it'll be on to the skeleton import and skinning stages.
After primarily using MEL for the past 2-3 years, I'm really seeing the benefit of using classes and object-oriented structure for a project like this, plus the fact that you can access the Maya API through Python is pretty damn useful.
.
They store multiple meshes per BRF file, this one is a set of 3 meshes from the 36-mesh set in "armors_b.brf". These also include LODs and material info.
In the end I hope to have a full and professional tool suite for working with Mount & Blade models and animations, built directly into Maya 2011 using Python for the scripting and Qt for the UI. Should be nice!
Hmm? What's MRV? I'm not bothering with PyMel since I'm actually not using much MEL command syntax at all, it's mostly Python file ops so far along with API functions through the OpenMaya Python libraries for doing all the heavy lifting.
There's like only two actual lines of Python MEL calls in there so far
That said, I might look more into PyMEL while working on this, I always kinda overlooked it since before Maya 2011 it never seemed to be properly supported.
@MoP: Out of curiosity what goes into writing an importer/exporter? Like how are you handling the writing of UV's, vertexes and stuff? Assume there's tricky math involved...Qt for UI is pretty straightforward. There was a video on the area on one of the maya blogs
rollin: Oh, I think I worked it out, "legendary wool milk pig" (thanks to a colleague who speaks some German), I understand now! Thanks
haiddasalami: Currently I'm just writing the importer, so the bulk of it is parsing the file format, reading in each block of data and storing/using it appropriately. For example once I have read in all of the vertex/UV/face/normal/skinning data from the file and stored it in a data structure, I can then pass all of this data into the API calls for MFnMesh to start constructing the mesh.
There's not actually that much maths involved at this point since everything is already calculated, you're mostly passing existing values to functions that do stuff with them.
Writing an exporter is pretty much the same thing in reverse - you determine your selection of things to export somehow (through UI most likely), then you use functions to get all the relevant data and store it in a logical manner. Then once you've stored it all you can write it out in blocks.
It depends on the model format - for example I've written an LWO importer in maxscript which was quite interesting, the LWO format is pretty good because it's chunk-based, so for every "chunk" of data, it specifies a 4-character string for the type of data in the chunk, then an integer value for how long (in bytes) the chunk is.
That way, if you read in the data type for that chunk and don't recognise it, you can simply read in the integer next and skip that number of bytes, which will take you to the next chunk.
IMHO this is the best way to structure a file since it means you don't even have to know or care about half the data in the file as long as you can read the stuff you want.
The nasty thing about this BRF format is that it's not structured in a chunk-based way (as such), so while it does define blocks of data, it doesn't define the length of the data in bytes, so you HAVE to have a method of reading each chunk even if you aren't going to use it, since you can't just simply skip the data, not knowing how long it is.
Anyway, at the moment about half of my Python script is simply helper functions for reading bytes, ints, floats, vectors, strings etc. from a file and passing them in nicely to my main script. Half the battle is knowing what the data is that you're reading in. The other half of the battle is swords.
basicly one of the core elements of the pipeline my flatmate is working on - i don't know much about coding but so far the codernerds who have been here working with it liked it much more than what autodesk offers them - python related that is
Replies
IfYouLikedItThenYouShouldHavePutAKeenOnIt.com
How does the system grid work? Does it generate an Id for every object and checks in into the field by position (like distance to left border divided by field width multiplied with width of a single box?). Would really appreciate a write down on your method there.
BTW- liking the flash Voxels Render.
Oh, the extra 1 (361, 1001) is actually the debug grid itself, a 5000 triangle plane.
e-freak - Finding which grid node you're on is ridiculously simple, that's one of the reasons I like grids.
You already have the grid segment size (gridSize / gridSegments) - so you simply find out which column and row you're on like this, making sure col and row are integers obviously -
col = ( player.x / segment_size );
row = ( player.z / segment_size );
Then once you know the current column and row any given object is on, you know the exact grid node, and can access it easily in a 2D or 1D array, as you know it's index.
Oh and of course if you have a 3D grid, you'd need to do the same thing in the y axis.
One of the reasons this grid is so fast, is I am not iterating through the grid. It's managed by the moving objects, they add/remove themselves and check for collisions. So that means I could have a huge grid with say 200,000 nodes running at the exact same speed as this one, because the amount of look ups and collisions etc would be the same.
Now I just have to develop a fast, solid per polygon collision routine (for the floors/walls etc of a level) and I can start making my first game. I can use this grid and a 3D version of this grid as a broad phase obviously, but I need to work on the actual polygon collision resolvement, colliding with multiple polygons etc.
Though this is just a tech demo, I'd like to make a fast, furious, stylised 3D shooter with similar visuals to this demo (but better/more developed obviously). Do you prefer the default flat shaded floor, or the Geometry Wars style pure wireframe after pressing R?
http://www.highperformancegraphics.org/program.html
going to look into it again
[ame]http://www.youtube.com/watch?v=n9gun7wQepQ[/ame]
try it with your own mug (yes you need a webcam to test it):
http://renderhjs.net/_tmp/soap/tracking.swf
use spacebar to swap the decoration on your face, d -key to swap the debug rendering.
its missing some of the interpolation stuff right now which makes it more smooth and natural as it dances and shakes at times but I am already quite pleased with the recognition rate (all based on that grey scale video input)
i used a cheap trick last time i worked on webcam tracking (color tracking) (not sure if it's applicable or you might come up with a better solution):
- Taking the average position of the tracker in the (up to) last 10 frames.
-- This smoothes out all jumping but it gives a slight lag (if you move your head too fast).
- So instead of taking the full number of frames you compare the last values
-- try to produce the average increase of values (linear function) in these last (ten) values
--- if none of the values "jump" (leaves the linear function from more than a tolerance value)
---- reduce the frames to three (still smoothes out the movement but is not noticable lag)
you can make the number of smoothing frames used change dynamically based on the difference from the linear function.
I got the go ahead from a candian chap who was the original creator of the 3ch topic generator to reinterpret his work.
Anyway I've been fucking my mind with allsorts of complicated stuff which is probably piss-easy to an actual programmer, but it's more fun than sudoku, right?
http://wallasaurus.deviantart.com/art/Topic-Generator-172651679
So I remade it. Now accepts neater file format, still pretty simple, allows multiple 'structures' to be composited together, recursively (so it is easy to break if you make a rubbish datase with infinite recursion in it) - I will add some checks to stop it going on forever next time i'm in the rat's maze looking at its glutionous underbelly.
Anyway, a bit of fun, and I think it is something I always wanted, which is as good a motivation as any to make a tool, am I right?
this question probably doesn't fit this thread too well, but I don't think it justifies a new thread.
Does anyone know of a script that aligns an object to another based on their selected vertices?
In the example above I know that the two selected vertices on the light grey object should be on the same positions as the two vertices on the dark grey object.
Now, if there was a script that rotates, scales and moves the light grey object in a way that the vertices are on the same position as on the other object, we wouldn't have to go through the process of align everything by hand, which probably would takes ages.
Started messing around with shaderfx; my try at a dry + damp + puddle material controlled by vertex painting. Inspired by the screens of Ryan James Smith's UDK advanced mesh paint material seen here: http://www.3dmotive.com/product-udk-mesh-paint
shaderfx network here: http://dl.dropbox.com/u/3580711/dampblend_sfx.jpg
sinistergfx... cool! Is that a UV panning function towards the bottom of the network?
YAY it works. My first script, well not done yet. Need to figure out how to save a query to a vector variable then Ill be golden
EDIT: Guess I should say what the script does haha. Well I do a lot of props modeling within the same scene file and just throw them around the level but if I ever want to use the prop again the pivot point is like way over there. So this puts the pivot in the center if it was moved, freezes transformations, querys world space of the pivot and moves it to 0,0,0. The xform query x etc is just placeholder and does not actually work. need to figure out how to save that to a variable and then gonna work on a UI. Also gonna include a batch FBX (profile for Unreal)/obj exporter in there and possibility of tweaking your pivot after its at 0,0,0
EDIT: Also grabbed a video of diffuse shader next up Spec, Normal and ambient color.
[ame]http://www.youtube.com/watch?v=5AanhjlH4pQ[/ame]
if anyone knows how to convert world space to tangent space using default maya nodes, that would be more ideal then using xNormal in this process, nothing against xNormal, just an extra step here that I'm sure can be cut out.
http://knol.google.com/k/koen-samyn/maxscript/2lijysgth48w1/35#
Thanks for sharing!
YAY it works now. Now to add more to it
I just dropped the lambert's diffuse: 0 and ambient color to 1,1,1. Seemed to work.
Also did you use this in any real scenario? Did you blend this with another normal map?
As for auto-refreshing, actually if you click on the tool your already in (like if your in move press W) it'll refresh too. Right now it's using scriptjobs to update when certain events happen, but exposed events are limited. I'd imagine their's a way to do it through the API (so as a plugin), but havn't really delved into that.
Been reverse-engineering the format based on their export script for Python, mostly pretty straightforward so far.
Currently I'm just building the raw mesh, next up is applying the specific vertex data like UVs, normals, tangents etc.
After that it'll be on to the skeleton import and skinning stages.
After primarily using MEL for the past 2-3 years, I'm really seeing the benefit of using classes and object-oriented structure for a project like this, plus the fact that you can access the Maya API through Python is pretty damn useful.
.
They store multiple meshes per BRF file, this one is a set of 3 meshes from the 36-mesh set in "armors_b.brf". These also include LODs and material info.
In the end I hope to have a full and professional tool suite for working with Mount & Blade models and animations, built directly into Maya 2011 using Python for the scripting and Qt for the UI. Should be nice!
There's like only two actual lines of Python MEL calls in there so far
That said, I might look more into PyMEL while working on this, I always kinda overlooked it since before Maya 2011 it never seemed to be properly supported.
haiddasalami: Currently I'm just writing the importer, so the bulk of it is parsing the file format, reading in each block of data and storing/using it appropriately. For example once I have read in all of the vertex/UV/face/normal/skinning data from the file and stored it in a data structure, I can then pass all of this data into the API calls for MFnMesh to start constructing the mesh.
There's not actually that much maths involved at this point since everything is already calculated, you're mostly passing existing values to functions that do stuff with them.
Writing an exporter is pretty much the same thing in reverse - you determine your selection of things to export somehow (through UI most likely), then you use functions to get all the relevant data and store it in a logical manner. Then once you've stored it all you can write it out in blocks.
It depends on the model format - for example I've written an LWO importer in maxscript which was quite interesting, the LWO format is pretty good because it's chunk-based, so for every "chunk" of data, it specifies a 4-character string for the type of data in the chunk, then an integer value for how long (in bytes) the chunk is.
That way, if you read in the data type for that chunk and don't recognise it, you can simply read in the integer next and skip that number of bytes, which will take you to the next chunk.
IMHO this is the best way to structure a file since it means you don't even have to know or care about half the data in the file as long as you can read the stuff you want.
The nasty thing about this BRF format is that it's not structured in a chunk-based way (as such), so while it does define blocks of data, it doesn't define the length of the data in bytes, so you HAVE to have a method of reading each chunk even if you aren't going to use it, since you can't just simply skip the data, not knowing how long it is.
Anyway, at the moment about half of my Python script is simply helper functions for reading bytes, ints, floats, vectors, strings etc. from a file and passing them in nicely to my main script. Half the battle is knowing what the data is that you're reading in. The other half of the battle is swords.
That's awesome you found out what it means, but the rest of us are still confused. :P
meaning something that provides everything.
several stuff from siggraph available now
http://advances.realtimerendering.com/s2010/index.html
http://bps10.idav.ucdavis.edu/
"MRV is a python framework based on wrapping the Maya API to speed up development and ease of use within pipelines using Autodesk Maya. "
http://packages.python.org/MRV/
basicly one of the core elements of the pipeline my flatmate is working on - i don't know much about coding but so far the codernerds who have been here working with it liked it much more than what autodesk offers them - python related that is