ดันป่วยระหว่างเที่ยวเลยอดซ่าไปโดดน้ำทะเลเล่นกับลูกหลานครับ
แต่ผมเตรียมหนังสือ MEL ไปนั่งอ่านวิธีเขียน Interface ประมาณกรอกค่า input ไปรัน script ทำนองนั้น
กลับมาเมื่อวานก็ดันไข้ขึ้นซะเลยนั่งพิมพ์ plugin ไปจมกองขี้มูกกันไป แต่ก็ดันมันจนเสร็จอย่างใน VDO ที่ท่านได้ชมนี่ล่ะครับ
เป็น plugin script แรกในชีวิตเลยครับ ยังมีอะไรอีกหลายอย่างที่อยากปรับปรุง แต่วรยุทธยังต่ำต้อยนัก ไว้ขอฝึกเพิ่มเติมจะหาโอกาศมา UP Version ต่อๆไปนะครับผม
ชาว MAYA อย่าลบืมไปลองใช้กันดูนะครับ เดี๋ยวผมจะมา Update VDO อีกอันเกี่ยวกับรายละเอียดการใช้ ข้อควรทำและไม่ควรทำต่างๆกับ path เอาแบบละเอียดอีกรอบล่ะกันครับผม
link ของ MEL ครับ
วันจันทร์ที่ 10 ตุลาคม พ.ศ. 2554
วันอังคารที่ 4 ตุลาคม พ.ศ. 2554
หาเรื่องใส่ตัว round 4
บอกตามตรงคิดว่าขั้นตอนนี้น่าจะมีเรื่องปวดหัวกว่านี้ โชคดีเรามี $dist กับ $inverse เตรียมพร้อมเสร็จสรรพ เหลือแค่หาเส้นรองวงเท่านั้นเองครับ
จากสูตรเส้นรอบวง 2πr π หรือ Pi คือ 22/7 r คือรัศมีผมเอา distance tool วัดกันดื้อเลย ได้มาดังนี้ครับ
ล้อใหญ่ = 10.997
ล้อเล็ก = 7.8644
แล้วก็นำมาเทียบบัญญัตยาค์เหมือนตอนสายพานแต่คราวนี้เราไม่เทียบกับ uValue แล้วเทียบกับรัศมีแทนครับดังนี้
ความยาว 10.997 ล้อหมุนได้ 360 องศา
ถ้าความยาว $dist จะหมุนได้ 360/7.8644*$dist แล้วนำไปบวกกับการหมุนก่อนหน้าได้เป็น script ดังนี้ครับ
float $bigWheelRot = $bigWheelRot+(360/10.997*$dist) ;
สรุป script ที่เพิ่มมา
float $bigWheelRot = $bigWheelRot+(360/10.997*$dist) ;
float $smallWheelRot = $smallWheelRot+(360/7.8644*$dist) ;
wheel1.rotateX = wheel2.rotateX = $bigWheelRot ;
wheel3.rotateX = wheel4.rotateX = wheel5.rotateX = $smallWheelRot ;
ส่วนท่อนเก่าผมไปเพิ่มนิดหน่อยว่าเวลาที่อยู่จุด 0 0 0 ให้ rotateX ของทุกล้อเป็น 0 ทั้งหมดเดี่ยวมา update สรุป script อีกทีในครั้งหน้าๆแล้วกันครับ จะได้ไม่ยืดยาว
หน้าตาประมาณนี้ครับ
ครั้งหน้าผมจะลองกับพื้นที่ไม่เรียบบ้าง แล้วหาวิธีคุม body รถให้เอียงตามพื้นด้วยนะครับ
จากสูตรเส้นรอบวง 2πr π หรือ Pi คือ 22/7 r คือรัศมีผมเอา distance tool วัดกันดื้อเลย ได้มาดังนี้ครับ
ล้อใหญ่ = 10.997
ล้อเล็ก = 7.8644
แล้วก็นำมาเทียบบัญญัตยาค์เหมือนตอนสายพานแต่คราวนี้เราไม่เทียบกับ uValue แล้วเทียบกับรัศมีแทนครับดังนี้
ความยาว 10.997 ล้อหมุนได้ 360 องศา
ถ้าความยาว $dist จะหมุนได้ 360/7.8644*$dist แล้วนำไปบวกกับการหมุนก่อนหน้าได้เป็น script ดังนี้ครับ
float $bigWheelRot = $bigWheelRot+(360/10.997*$dist) ;
สรุป script ที่เพิ่มมา
float $bigWheelRot = $bigWheelRot+(360/10.997*$dist) ;
float $smallWheelRot = $smallWheelRot+(360/7.8644*$dist) ;
wheel1.rotateX = wheel2.rotateX = $bigWheelRot ;
wheel3.rotateX = wheel4.rotateX = wheel5.rotateX = $smallWheelRot ;
ส่วนท่อนเก่าผมไปเพิ่มนิดหน่อยว่าเวลาที่อยู่จุด 0 0 0 ให้ rotateX ของทุกล้อเป็น 0 ทั้งหมดเดี่ยวมา update สรุป script อีกทีในครั้งหน้าๆแล้วกันครับ จะได้ไม่ยืดยาว
หน้าตาประมาณนี้ครับ
ครั้งหน้าผมจะลองกับพื้นที่ไม่เรียบบ้าง แล้วหาวิธีคุม body รถให้เอียงตามพื้นด้วยนะครับ
วันจันทร์ที่ 3 ตุลาคม พ.ศ. 2554
หาเรื่องใส่ตัว round 3
ขยับกระดุกกระดิ๊ก
- เริ่มจากผมสร้าง locator ไว้ตัวนึงเพื่อเช็คระยะทางชื่อ distCheckLoc
- ผมสร้าง controller ชื่อ trackCtrl เป็นตัวที่ animator เอาไป aniamate นะครับ
-สร้างตัวแปรแบบ vector มาเก็บค่าตำแหน่งเก่าของ distCheckLoc ชื่อ $oldPos นะครับ
vector $oldPos = <> ;
-สร้างตัวแปรมาเก็บค่าตำแหน่งที่เกิดจาก animatorขยับ trackCtrl ชื่อ $new
vector $newPos = <> ;
-เราก็หาระยะที่เคลื่อนที่ไปได้จาก เอาระยะเก่าลบด้วยระยะเก่า มาใส่ในตัวแปรใหม่ไว้ก่อนชื่อ $dist ครับ
float $dist = mag($newPos - $oldPos) ;
- ตอนนี้เรารู้ระยะทางที่เราลาก conroller ไปได้แระครับ ถ้าเราจะทำให้สายพานหมุนเราต้องรู้ความยาวของ pathก่อนนะครับ
ปัญหานี้ผมแก้โดยใช้ measure tool / arc length tool คลิ๊กไปที่ปลายของ path ได้เลยครับ ผมไม่ได้ copy ค่ามาโดยตรงนะครับแต่ใข้ผ่าน attr ชื่อ arcLengthDimensionShape1.arcLength แทนนะครับ
float $arcLength = arcLengthDimensionShape1.arcLength ;
- ถึงเวลา บัญญัตยางค์แล้วนะครับ
ถ้าเรามีความยาว $arcLength เท่ากับ uValue เป็น 1
ถ้าความยาวเท่ากับ $dist จะเป็น uValue เท่าไหร่ เขียนเป็น expression ดังนี้
float $uChange = 1/$arcLength*$dist ;
- break connection ของ uValue ใน motionPath1.uValue ก่อนนะครับ ไม่งั้นพิมพ์ melใส่ไม่ได้นะครับ
motionPath1.uValue = (motionPath1.uValue + $uChange) % 1 ;
% 1 หมายถึงให้ค่าวนเวียนอยู่ใน loop จาก 0 - 1 นั่นเองครับ
- ตอนนี้สายพานเราเคลื่อนที่ไปข้างหน้าตามระยะที่เราลากได้แล้วนะครับ แต่ติดตรงถอยหลังแล้วสายพานเคลื่อนที่ผิดทิศครับ ขั้นตอนนี้ค่อนข้าง เช็ค condition ซับซ้อนมากมาย ผมขอสรุปคร่าวๆล่ะกันครับ
เป้าหมายคือ ใช้ตัวแปร ที่ชื่อ $inverse ชึ่งมันต้องการ 2 ค่า คือ +1 เดินหน้า -1 ถอยหลังครับ ลองแกะดูก่อนนะครับผม ถ้างงสอบถามได้ครับ
condition ที่ผมเช็ค พบว่ามีปัญหาเวลาเลี้ยวทุกมุมฉาก เลยหาวิธีแก้ได้ mel มาดังนี้ครับผม
float $angle = sign(trackCtrl.rotateY) * ((abs(trackCtrl.rotateY))%360) ;
if ($dirCheck < 0) {
$inverse = -1 ;
}
if ($angle < -90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle < -90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle < -270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle < -270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
if ($angle > 90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle > 90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle > 270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle > 270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
- เอา $inverse ที่ได้ไปคุณ กับ $dist ที่เราทำไว้ตอนแรกครับ
float $dist = (mag($newPos - $oldPos))*$inverse ;
- ขอรวมร่างกะ mel เดิมได้มาหน้าตายังงี้ครับ
vector $oldPos = <> ;
vector $newPos = <> ;
float $inverse = 1 ;
float $dirCheck = $newPos.z - $oldPos.z ;
float $angle = sign(trackCtrl.rotateY) * ((abs(trackCtrl.rotateY))%360) ;
if ($dirCheck < 0) {
$inverse = -1 ;
}
if ($angle < -90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle < -90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle < -270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle < -270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
if ($angle > 90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle > 90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle > 270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle > 270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
float $dist = (mag($newPos - $oldPos))*$inverse ;
distCheckLoc.translateX = $newPos.x ;distCheckLoc.translateY = $newPos.y ;distCheckLoc.translateZ = $newPos.z ;
float $arcLength = arcLengthDimensionShape1.arcLength ;
float $uChange = 1/$arcLength*$dist ;
if (trackCtrl.translateX == 0 && trackCtrl.translateY == 0 && trackCtrl.translateZ == 0){
motionPath1.uValue = 0 ;
}
else{
if ($inverse < 0){
motionPath1.uValue = (motionPath1.uValue + (1-abs($uChange*$inverse))) % 1 ;
}
else{
motionPath1.uValue = (motionPath1.uValue + ($uChange*$inverse)) % 1 ;
}
}
float $numberOfFoot = 36 ;
float $gap = 1/$numberOfFoot ;
for ($i = 2 ; $i <= $numberOfFoot ; $i++){
string $txt = "motionPath"+$i+".uValue" ;
float $uValue = motionPath1.uValue ;
float $uValueCheck = $uValue-($gap*($i-1));
if ($uValueCheck <= 0) {
$uValueCheck = 1-(abs($uValue-($gap*($i-1)))) ;
}
setAttr $txt $uValueCheck ;
}
ตัวสำเร็จมีหน้าตายังงี้ครับผม
ครั้งหน้าผมจะเริ่มหมุนล้อตามสายพานบ้างครับ น่าจะชิวๆเพราะจะคล้ายๆการหมุนสายพาน (มั๊ง ?) ยังไม่ได้ลองเลยครับ หนทางอีกยาวไกล
- เริ่มจากผมสร้าง locator ไว้ตัวนึงเพื่อเช็คระยะทางชื่อ distCheckLoc
- ผมสร้าง controller ชื่อ trackCtrl เป็นตัวที่ animator เอาไป aniamate นะครับ
-สร้างตัวแปรแบบ vector มาเก็บค่าตำแหน่งเก่าของ distCheckLoc ชื่อ $oldPos นะครับ
vector $oldPos = <
-สร้างตัวแปรมาเก็บค่าตำแหน่งที่เกิดจาก animatorขยับ trackCtrl ชื่อ $new
vector $newPos = <
-เราก็หาระยะที่เคลื่อนที่ไปได้จาก เอาระยะเก่าลบด้วยระยะเก่า มาใส่ในตัวแปรใหม่ไว้ก่อนชื่อ $dist ครับ
float $dist = mag($newPos - $oldPos) ;
- ตอนนี้เรารู้ระยะทางที่เราลาก conroller ไปได้แระครับ ถ้าเราจะทำให้สายพานหมุนเราต้องรู้ความยาวของ pathก่อนนะครับ
ปัญหานี้ผมแก้โดยใช้ measure tool / arc length tool คลิ๊กไปที่ปลายของ path ได้เลยครับ ผมไม่ได้ copy ค่ามาโดยตรงนะครับแต่ใข้ผ่าน attr ชื่อ arcLengthDimensionShape1.arcLength แทนนะครับ
float $arcLength = arcLengthDimensionShape1.arcLength ;
- ถึงเวลา บัญญัตยางค์แล้วนะครับ
ถ้าเรามีความยาว $arcLength เท่ากับ uValue เป็น 1
ถ้าความยาวเท่ากับ $dist จะเป็น uValue เท่าไหร่ เขียนเป็น expression ดังนี้
float $uChange = 1/$arcLength*$dist ;
- break connection ของ uValue ใน motionPath1.uValue ก่อนนะครับ ไม่งั้นพิมพ์ melใส่ไม่ได้นะครับ
motionPath1.uValue = (motionPath1.uValue + $uChange) % 1 ;
% 1 หมายถึงให้ค่าวนเวียนอยู่ใน loop จาก 0 - 1 นั่นเองครับ
- ตอนนี้สายพานเราเคลื่อนที่ไปข้างหน้าตามระยะที่เราลากได้แล้วนะครับ แต่ติดตรงถอยหลังแล้วสายพานเคลื่อนที่ผิดทิศครับ ขั้นตอนนี้ค่อนข้าง เช็ค condition ซับซ้อนมากมาย ผมขอสรุปคร่าวๆล่ะกันครับ
เป้าหมายคือ ใช้ตัวแปร ที่ชื่อ $inverse ชึ่งมันต้องการ 2 ค่า คือ +1 เดินหน้า -1 ถอยหลังครับ ลองแกะดูก่อนนะครับผม ถ้างงสอบถามได้ครับ
condition ที่ผมเช็ค พบว่ามีปัญหาเวลาเลี้ยวทุกมุมฉาก เลยหาวิธีแก้ได้ mel มาดังนี้ครับผม
float $angle = sign(trackCtrl.rotateY) * ((abs(trackCtrl.rotateY))%360) ;
if ($dirCheck < 0) {
$inverse = -1 ;
}
if ($angle < -90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle < -90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle < -270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle < -270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
if ($angle > 90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle > 90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle > 270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle > 270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
- เอา $inverse ที่ได้ไปคุณ กับ $dist ที่เราทำไว้ตอนแรกครับ
float $dist = (mag($newPos - $oldPos))*$inverse ;
- ขอรวมร่างกะ mel เดิมได้มาหน้าตายังงี้ครับ
vector $oldPos = <
vector $newPos = <
float $inverse = 1 ;
float $dirCheck = $newPos.z - $oldPos.z ;
float $angle = sign(trackCtrl.rotateY) * ((abs(trackCtrl.rotateY))%360) ;
if ($dirCheck < 0) {
$inverse = -1 ;
}
if ($angle < -90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle < -90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle < -270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle < -270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
if ($angle > 90 && $dirCheck < 0 ) {
$inverse = 1 ;
}
if ($angle > 90 && $dirCheck > 0 ) {
$inverse = -1 ;
}
if ($angle > 270 && $dirCheck > 0 ) {
$inverse = 1 ;
}
if ($angle > 270 && $dirCheck < 0 ) {
$inverse = -1 ;
}
float $dist = (mag($newPos - $oldPos))*$inverse ;
distCheckLoc.translateX = $newPos.x ;distCheckLoc.translateY = $newPos.y ;distCheckLoc.translateZ = $newPos.z ;
float $arcLength = arcLengthDimensionShape1.arcLength ;
float $uChange = 1/$arcLength*$dist ;
if (trackCtrl.translateX == 0 && trackCtrl.translateY == 0 && trackCtrl.translateZ == 0){
motionPath1.uValue = 0 ;
}
else{
if ($inverse < 0){
motionPath1.uValue = (motionPath1.uValue + (1-abs($uChange*$inverse))) % 1 ;
}
else{
motionPath1.uValue = (motionPath1.uValue + ($uChange*$inverse)) % 1 ;
}
}
float $numberOfFoot = 36 ;
float $gap = 1/$numberOfFoot ;
for ($i = 2 ; $i <= $numberOfFoot ; $i++){
string $txt = "motionPath"+$i+".uValue" ;
float $uValue = motionPath1.uValue ;
float $uValueCheck = $uValue-($gap*($i-1));
if ($uValueCheck <= 0) {
$uValueCheck = 1-(abs($uValue-($gap*($i-1)))) ;
}
setAttr $txt $uValueCheck ;
}
ตัวสำเร็จมีหน้าตายังงี้ครับผม
ครั้งหน้าผมจะเริ่มหมุนล้อตามสายพานบ้างครับ น่าจะชิวๆเพราะจะคล้ายๆการหมุนสายพาน (มั๊ง ?) ยังไม่ได้ลองเลยครับ หนทางอีกยาวไกล
วันอาทิตย์ที่ 2 ตุลาคม พ.ศ. 2554
หาเรื่องใส่ตัว round 2
ขั้นนี้เป้าหมายอยู่ที่ทำให้สายพานในแต่ละข้อ (ขอเรียกว่า track) วิ่งตามๆกันไป เป็นใช้ได้ครับ โมเดลที่ใช้เป็นโมเดลไกด์เฉยๆ ตัวที่จะทำออกแบบไว้แล้วแต่ยังไม่ค่อยเรียบร้อยนะครับ เริ่มเลย
1. ผมใช้วิธี motion path เพราะฉะนั้นต้องสร้าง path ด้วย curve ก่อนครับ เนื่องจาก plan ว่าจะทำ dynamic กับมันด้วยในอนาคตเลยต้องทำให้ curve เป็น closed curve ก่อนนะครับ ไม่งั้นพอทำ dynamic แล้วเส้นขาดจะเซ็งเป็ดเอาเปล่าๆ

2 จากการประมาณแล้ว path นี้ต้องใช้ track ที่ปั้นรอไว้จำนวน 36 อันจึงจะทำให้ต่อสวยพอดี ขออนุญาติข้ามขั้นตอนที่ไม่เกี่ยวข้องไปนะครับ
ผมไล่ attach motion path ไปทุกอันจนครบ ตอนไล่ทำเกือบเขียน mel แล้วคิดได้ว่าค่อยๆทำเดี๋ยวก็เสร็จนะครับ ขออนุญาติข้ามขั้นตอน
ปรับให้วัตถุหันให้ถูกทางไปนะครับ ลองปรับ up axis กะ front axis ดูเองล่ะกัน
ตอนนี้ทั้ง 36 tracks ไปกองรวมกันอยู่ที่จุดเริ่มต้นของ curve


3 track เคลื่อนที่ไปตาม path ได้เพราะ Attribute ตัวนึงใน motion path ชื่อ uValue ครับ เป็น Attr แบบfloat มีค่าอยู่ระหว่าง 0-1
0 คือตำแหน่งเริ่มของ curve
1 คือตำแหน่งปลายของ curve
ในที่นี้เราทำ closed curve ไว้เมื่อมัน animation จาก 0 ไป 1 มันจึงวนกลับมาที่เดิมนั่นเองครับ
4. เราต้องการให้ track2,track3,....track36 ไหลตามการเลื่อนที่ของ track1 ไปเราก็แค่ไปดึงค่า uValue ของ
motionPath ของ track1 มาลดค่าลงไปอีกนิสเพื่อให้เคลื่อนที่เหลื่อมกันเท่านั้นเองครับ ตอนนี้ผมขอยกตัวอย่าง การเคลื่อนที่แค่ track1 กะ track2 ก่อนจะได้ดู script ง่ายๆดีกว่านะครับ
***** ก่อนใส่ expression อย่าลืมไป break connection ตัว uValue ของ motionPath2 ไปทุกตัวจนถึง motionPath36 ก่อน ไม่งั้นค่า key animation จะไปขวางการใส่ script ของเรานะครับ
motionPath2.uValue = motionPath1.uValue - ระยะห่าง(float) ;//ระยะห่างในที่นี้เป็นตัวเลขนะครับ
สมมุติผมให้มันเหลื่อมกัน 0.1 หน่วย ก็จะเป็น motionPath2.uValue = motionPath1.uValue - .1 ;
ฮะฮ้า !!! ง่ายไหมล่ะครับ พอเรา play ดูจะพบว่าช่วง frame ต้นๆจะ error ครับ
เพราะตอนต้น frame นั้น motionPath1.uValue มีค่า animation เป็น 0 0 ลบด้วย .1 มีค่าเป็น -.9 แต่ uValue มี
ค่าได้แค่ 0-1 มันก็ error จิคร้าบ ต้องรอจนถึง frame ที่ motionPath1.uValue = .1 ก่อน ถึงจะไม่ error แล้ว track2 ก็จะเริ่มวิ่งตาม track1 นั่นเองครับ
5. เราแก้ปัญหานี้ง่ายๆ โดยการกำหนดว่า ถ้าค่า uValue น้อยกว่า 0 ก็ให้ตัวมัน(ที่ไม่ติดค่าลบ) ไปลบกับ 1 นั่นเองครับ เราก็จะได้ตำแหน่งที่ถูกต้องออกมา
float $uValueCheck = motionPath1.uValue -.1;
if ($uValueCheck <= 0) {
$uValueCheck = 1-(abs(motionPath1.uValue-.1)) ;
}
setAttr motionPath2.uValue $uValueCheck ;
}
abs(ตัวเลข) คือการแปลงให้ค่าเป็นบวกเสมอนั่นเองครับ
เมื่อพิมพ์เสร็จแล้วเรามาลองเช็คค่าดูนะครับ สมสุติเป็น frame แรก(ที่มีปัญหา motionPath1.uValue = 0)
แทนค่าใน script ดูได้ดังนี้
$uValueCheck = 1-(abs(motionPath1.uValue-.1))
1 - (abs(0-.1)) มีค่าเท่ากับ .1 ซึ่งทำให้มีค่าถูต้องพอดีกับตำแหน่งใน path พอดีครับ
6. เรามี track ตั้ง 36 อัน เพราะฉะนั้น แต่ละอันมีค่า uValue เฉลี่ย 1หารด้วย36 นั่นเองครับ เขียนเป็น script ดังนี้
float $numberOfFoot = 36 ;
float $gap = 1/$numberOfFoot ;
ใช้ $numberOfFoot เพื่อเตือนสติตัวเองว่ามี 36 อันนั่นเองครับผม เลยอนุญาติเพิ่มมาอีกบรรทัดนึง
โชคร้ายที่เรามี วัตถุที่ต้องเขียนตั้ง 36 อันเลยต้องใช้ condition แบบ for มาช่วยครับ ถ้าจะอธิบายจะเยิ่นเย้อเกิน ขอสรุป script ใน round 3 ไว้เพียงนี้ก่อนล่ะกันครับ
float $numberOfFoot = 36 ;
float $gap = 1/$numberOfFoot ;
for ($i = 2 ; $i <= $numberOfFoot ; $i++){
string $txt = "motionPath"+$i+".uValue" ;
float $uValue = motionPath1.uValue ;
float $uValueCheck = $uValue-($gap*($i-1));
if ($uValueCheck <= 0) {
$uValueCheck = 1-(abs($uValue-($gap*($i-1)))) ;
}
setAttr $txt $uValueCheck ;
}

ผลลัพธ์ที่ได้เป็นตาม VDO นี้นะครับ
รอบหน้าเป็นตาของตัว check ระยะบ้างยังไม่ได้ทำเลย แต่น่าจะเอาอยู่ครับ
สวัสดี
1. ผมใช้วิธี motion path เพราะฉะนั้นต้องสร้าง path ด้วย curve ก่อนครับ เนื่องจาก plan ว่าจะทำ dynamic กับมันด้วยในอนาคตเลยต้องทำให้ curve เป็น closed curve ก่อนนะครับ ไม่งั้นพอทำ dynamic แล้วเส้นขาดจะเซ็งเป็ดเอาเปล่าๆ

2 จากการประมาณแล้ว path นี้ต้องใช้ track ที่ปั้นรอไว้จำนวน 36 อันจึงจะทำให้ต่อสวยพอดี ขออนุญาติข้ามขั้นตอนที่ไม่เกี่ยวข้องไปนะครับ
ผมไล่ attach motion path ไปทุกอันจนครบ ตอนไล่ทำเกือบเขียน mel แล้วคิดได้ว่าค่อยๆทำเดี๋ยวก็เสร็จนะครับ ขออนุญาติข้ามขั้นตอน
ปรับให้วัตถุหันให้ถูกทางไปนะครับ ลองปรับ up axis กะ front axis ดูเองล่ะกัน
ตอนนี้ทั้ง 36 tracks ไปกองรวมกันอยู่ที่จุดเริ่มต้นของ curve


3 track เคลื่อนที่ไปตาม path ได้เพราะ Attribute ตัวนึงใน motion path ชื่อ uValue ครับ เป็น Attr แบบfloat มีค่าอยู่ระหว่าง 0-1
0 คือตำแหน่งเริ่มของ curve
1 คือตำแหน่งปลายของ curve
ในที่นี้เราทำ closed curve ไว้เมื่อมัน animation จาก 0 ไป 1 มันจึงวนกลับมาที่เดิมนั่นเองครับ
4. เราต้องการให้ track2,track3,....track36 ไหลตามการเลื่อนที่ของ track1 ไปเราก็แค่ไปดึงค่า uValue ของ
motionPath ของ track1 มาลดค่าลงไปอีกนิสเพื่อให้เคลื่อนที่เหลื่อมกันเท่านั้นเองครับ ตอนนี้ผมขอยกตัวอย่าง การเคลื่อนที่แค่ track1 กะ track2 ก่อนจะได้ดู script ง่ายๆดีกว่านะครับ
***** ก่อนใส่ expression อย่าลืมไป break connection ตัว uValue ของ motionPath2 ไปทุกตัวจนถึง motionPath36 ก่อน ไม่งั้นค่า key animation จะไปขวางการใส่ script ของเรานะครับ
motionPath2.uValue = motionPath1.uValue - ระยะห่าง(float) ;//ระยะห่างในที่นี้เป็นตัวเลขนะครับ
สมมุติผมให้มันเหลื่อมกัน 0.1 หน่วย ก็จะเป็น motionPath2.uValue = motionPath1.uValue - .1 ;
ฮะฮ้า !!! ง่ายไหมล่ะครับ พอเรา play ดูจะพบว่าช่วง frame ต้นๆจะ error ครับ
เพราะตอนต้น frame นั้น motionPath1.uValue มีค่า animation เป็น 0 0 ลบด้วย .1 มีค่าเป็น -.9 แต่ uValue มี
ค่าได้แค่ 0-1 มันก็ error จิคร้าบ ต้องรอจนถึง frame ที่ motionPath1.uValue = .1 ก่อน ถึงจะไม่ error แล้ว track2 ก็จะเริ่มวิ่งตาม track1 นั่นเองครับ
5. เราแก้ปัญหานี้ง่ายๆ โดยการกำหนดว่า ถ้าค่า uValue น้อยกว่า 0 ก็ให้ตัวมัน(ที่ไม่ติดค่าลบ) ไปลบกับ 1 นั่นเองครับ เราก็จะได้ตำแหน่งที่ถูกต้องออกมา
float $uValueCheck = motionPath1.uValue -.1;
if ($uValueCheck <= 0) {
$uValueCheck = 1-(abs(motionPath1.uValue-.1)) ;
}
setAttr motionPath2.uValue $uValueCheck ;
}
abs(ตัวเลข) คือการแปลงให้ค่าเป็นบวกเสมอนั่นเองครับ
เมื่อพิมพ์เสร็จแล้วเรามาลองเช็คค่าดูนะครับ สมสุติเป็น frame แรก(ที่มีปัญหา motionPath1.uValue = 0)
แทนค่าใน script ดูได้ดังนี้
$uValueCheck = 1-(abs(motionPath1.uValue-.1))
1 - (abs(0-.1)) มีค่าเท่ากับ .1 ซึ่งทำให้มีค่าถูต้องพอดีกับตำแหน่งใน path พอดีครับ
6. เรามี track ตั้ง 36 อัน เพราะฉะนั้น แต่ละอันมีค่า uValue เฉลี่ย 1หารด้วย36 นั่นเองครับ เขียนเป็น script ดังนี้
float $numberOfFoot = 36 ;
float $gap = 1/$numberOfFoot ;
ใช้ $numberOfFoot เพื่อเตือนสติตัวเองว่ามี 36 อันนั่นเองครับผม เลยอนุญาติเพิ่มมาอีกบรรทัดนึง
โชคร้ายที่เรามี วัตถุที่ต้องเขียนตั้ง 36 อันเลยต้องใช้ condition แบบ for มาช่วยครับ ถ้าจะอธิบายจะเยิ่นเย้อเกิน ขอสรุป script ใน round 3 ไว้เพียงนี้ก่อนล่ะกันครับ
float $numberOfFoot = 36 ;
float $gap = 1/$numberOfFoot ;
for ($i = 2 ; $i <= $numberOfFoot ; $i++){
string $txt = "motionPath"+$i+".uValue" ;
float $uValue = motionPath1.uValue ;
float $uValueCheck = $uValue-($gap*($i-1));
if ($uValueCheck <= 0) {
$uValueCheck = 1-(abs($uValue-($gap*($i-1)))) ;
}
setAttr $txt $uValueCheck ;
}

ผลลัพธ์ที่ได้เป็นตาม VDO นี้นะครับ
รอบหน้าเป็นตาของตัว check ระยะบ้างยังไม่ได้ทำเลย แต่น่าจะเอาอยู่ครับ
สวัสดี
วันเสาร์ที่ 1 ตุลาคม พ.ศ. 2554
หาเรื่องใส่ตัว round 1
วิเคราห์ปัญหาของล้อตีนตะขาบกันก่อนดีฟ่า ขอให้นึกภาพตีนตะขาบรถถังหรือรถไถไว้นะครับ
1 เส้น path ของการเคลื่อนที่ไม่ได้เป็นทรงกลมแบบล้อรถยนต์ ทำให้เราไม่สามารถ rotate แบบมี center ได้ ?
ผมเล็งไว้ 2 แบบแล้วคือ ไม่ motion path ก็ wire defrom แต่ wire นี่ถ้าจะปัญหาเยอะกว่านะเนี่ย เดี๋ยวลองเอา motion path มาเล่นดูก่อนดีกว่าครับ

2 จะควบคุมข้อแต่ละข้อของสายพานมีการเคลื่อนที่เหมือนโซ่จักรยานได้ไง ?
ถ้าเรากำหนดจุดอ้างอิงไว้ แล้ว offset ตำแหน่งย้อนไปด้านหลังเราก็จะได้ตำแหน่งของข้อถัดๆไป

3 จะทำไงให้เรา animation รถให้เคลื่อนที่ แล้วสายพานหมุนอัตโนมัติ ?
ต้องหาระยะที่เคลื่อนที่ไป แปลงตำแหน่งที่เคลื่อนที่จาก vector(ตำแหน่งแบบ x,y,z) ให้เป็น float (ระยะทางที่เคลื่อนที่)
ถ้าเรารู้ระยะของสายพานเราก็น่าจะสามารถเอามาเทียบบัญญัตยางค์ กับการเคลื่อนที่ครบรอบของ motion path
4 ทำไงให้ล้อหมุนไม่เท่ากันเวลาเลี้ยว ?
ข้อนี้ผมมีไอเดียแระ ก็แค่ check ระยะทาง อิสระแต่ละข้างเท่านั้นเอง อิ อิ
5 จะทำไงให้เคลื่อนที่ผ่านเนินหรือ ก้อนหิน แล้วเส้น path มีการเปลี่ยนรูปร่างตามพื้นถนนที่ไม่ราบเรียบ ?
อันนี้เล็งๆไว้ 2 วิธี
1 ใช้ dynamic เคลื่อนที่ผ่าน collision object
ที่ดูอยู่ก็มี nCloth กะ hair ครับ
2 ใช้ constrait หรือ mel หาจุดสูงสุดของพื้น(y)ที่อยู่ในกัด (x,z)ที่กำหนด
อันนี้มืดแปดด้าน ยังหาวิธีเขียนไม่ได้เลยแต่ถ้าได้จะเจ๋งมากเพราะไม่ต้อง simulate
ในที่นี้นึกออกอีกอย่างว่าล้อมันควรหมด dynamic เวลาอยู่ใกล้กับล้อที่ขับเคลื่อนมัน หรือเวลาติดกับเฟืองจักรยานนั่นเอง
ยังมีรายละเอียดอีกแน่นอนแต่ยังนึกไม่ออกเอาแค่นี้ก่อนนะครับผม
1 เส้น path ของการเคลื่อนที่ไม่ได้เป็นทรงกลมแบบล้อรถยนต์ ทำให้เราไม่สามารถ rotate แบบมี center ได้ ?
ผมเล็งไว้ 2 แบบแล้วคือ ไม่ motion path ก็ wire defrom แต่ wire นี่ถ้าจะปัญหาเยอะกว่านะเนี่ย เดี๋ยวลองเอา motion path มาเล่นดูก่อนดีกว่าครับ

2 จะควบคุมข้อแต่ละข้อของสายพานมีการเคลื่อนที่เหมือนโซ่จักรยานได้ไง ?
ถ้าเรากำหนดจุดอ้างอิงไว้ แล้ว offset ตำแหน่งย้อนไปด้านหลังเราก็จะได้ตำแหน่งของข้อถัดๆไป

3 จะทำไงให้เรา animation รถให้เคลื่อนที่ แล้วสายพานหมุนอัตโนมัติ ?
ต้องหาระยะที่เคลื่อนที่ไป แปลงตำแหน่งที่เคลื่อนที่จาก vector(ตำแหน่งแบบ x,y,z) ให้เป็น float (ระยะทางที่เคลื่อนที่)
ถ้าเรารู้ระยะของสายพานเราก็น่าจะสามารถเอามาเทียบบัญญัตยางค์ กับการเคลื่อนที่ครบรอบของ motion path
4 ทำไงให้ล้อหมุนไม่เท่ากันเวลาเลี้ยว ?
ข้อนี้ผมมีไอเดียแระ ก็แค่ check ระยะทาง อิสระแต่ละข้างเท่านั้นเอง อิ อิ
5 จะทำไงให้เคลื่อนที่ผ่านเนินหรือ ก้อนหิน แล้วเส้น path มีการเปลี่ยนรูปร่างตามพื้นถนนที่ไม่ราบเรียบ ?
อันนี้เล็งๆไว้ 2 วิธี
1 ใช้ dynamic เคลื่อนที่ผ่าน collision object
ที่ดูอยู่ก็มี nCloth กะ hair ครับ
2 ใช้ constrait หรือ mel หาจุดสูงสุดของพื้น(y)ที่อยู่ในกัด (x,z)ที่กำหนด
อันนี้มืดแปดด้าน ยังหาวิธีเขียนไม่ได้เลยแต่ถ้าได้จะเจ๋งมากเพราะไม่ต้อง simulate
ในที่นี้นึกออกอีกอย่างว่าล้อมันควรหมด dynamic เวลาอยู่ใกล้กับล้อที่ขับเคลื่อนมัน หรือเวลาติดกับเฟืองจักรยานนั่นเอง
ยังมีรายละเอียดอีกแน่นอนแต่ยังนึกไม่ออกเอาแค่นี้ก่อนนะครับผม
ประกาศโปรเจค "หาเรื่องใส่ตัว ครั้งที่ 1 ล้อตีนตะขาบ"
หาเรื่องใส่ตัว เป็นงานทดลองทำเรื่องที่ยังไม่รู้หรือไม่เข้าใจมาทดลองแก้ปัญหาแบบชิวๆ
ถ้าแก้ได้ก็มีฮา
ถ้าไม่ได้ก็เนียนๆ กันไป
เชิญพี่น้องผองเพื่อน ลูกศิษย์ทั้งหลายมาร่วมแจมได้ตามสะดวก ไม่จำกัด softwareไอเดีย เทคนิค
หรือจะเป็นกองเชียร์ ก็เป็นพระคุณครับ คริ คริ
งานแรกเป็นปัญหาที่เกิดตอนตรวจการบ้านเห็นงานนักเรียนทำมา เป็นตีนตะขาบของรถถังเลยเกิดไอเดียว่าเราจะ rig มันยังไงให้ใช้งานง่ายและอัตโนมิติ
มากๆเวลาเรา animate ครับ
ผมมีไอเดียบางส่วนแล้วประมาณ 25% อีก 75 เดี๋ยวใช้วรยุทธมั่วนิ่ม เอาแล้วกันนะครับ จะหมู่หรือจ่า คอยชม เอิ๊ก
เริ่มกันเลย !!!
ถ้าแก้ได้ก็มีฮา
ถ้าไม่ได้ก็เนียนๆ กันไป
เชิญพี่น้องผองเพื่อน ลูกศิษย์ทั้งหลายมาร่วมแจมได้ตามสะดวก ไม่จำกัด softwareไอเดีย เทคนิค
หรือจะเป็นกองเชียร์ ก็เป็นพระคุณครับ คริ คริ
งานแรกเป็นปัญหาที่เกิดตอนตรวจการบ้านเห็นงานนักเรียนทำมา เป็นตีนตะขาบของรถถังเลยเกิดไอเดียว่าเราจะ rig มันยังไงให้ใช้งานง่ายและอัตโนมิติ
มากๆเวลาเรา animate ครับ
ผมมีไอเดียบางส่วนแล้วประมาณ 25% อีก 75 เดี๋ยวใช้วรยุทธมั่วนิ่ม เอาแล้วกันนะครับ จะหมู่หรือจ่า คอยชม เอิ๊ก
เริ่มกันเลย !!!
วันจันทร์ที่ 19 กันยายน พ.ศ. 2554
hendrix songbook
http://www.4shared.com/file/Te7pYrXq/Jimi_Hendrix_-_Guitar_Signatur.html
โน้ตพร้อม TAB ของท่านพี่ hendrix เพื่อใครยังไม่มีไว้ครอบครองครับพ้ม
โน้ตพร้อม TAB ของท่านพี่ hendrix เพื่อใครยังไม่มีไว้ครอบครองครับพ้ม
สมัครสมาชิก:
บทความ (Atom)
เพื่อนๆ
คลังบทความของบล็อก
เกี่ยวกับฉัน
- jedi15122002@hotmail.com
- นนทบุรี, กลาง, Thailand
- ชื่อเพื่อนเรียกตุ๊กแกครับ ตอนหลังมีลูกชายเลยเอามาตั้งเป็นนามแฝง น้องเจไดผู้เกิดวันที่ 15 12 2002 ไม่มีลืมอยู่แล้ว เป็นชาว 3D แต่บางครั้งก็เผลอไปเป็นชาว 2D บางช่วงฟุ้งซ่านมากๆก็เอาแต่หัดเปียโน เอาแน่เอานอนได้ยากจริงๆ ตอนนี้รับบทเป็นพ่อพิมพ์ของชาติ เป็น อ.พิเศษที่ ม.รังสิต (VFS2) กับ ม.ธุรกิจบัณฑิต(เบสิคมายา) แล้วก็รับงาน 3d ฟรีแลนซ์ ทั่วราชอาณาจักรครับผม