ソラマメブログ

2008年11月17日

蝶の作り方 - 逐次解説

逐次解説シリーズ というわけでもないが
-----
これやると無理やりでも 読まなくちゃいけなくなるからね
-----
というわけで 蝶の逐次解説やってみようかなと... w
-----
まず どんな 蝶 かというと
-----

-----
こんなです...
-----
で 自分が作ったのは 羽ばたかせるスクリプト だけで 動きは sworm という
-----
LSL Swarm Script For Second Life - Make Birds & Bees ≪ Second Life Conceptual Creations
-----
にあるスクリプトを使っている
-----
今回の目玉は これを解説してみようと(実はまだちゃんと読んだことない w)
-----
というわけで 次回以降 sworm を読んでみる予定
-----
というわけで 今回は 羽ばたかせるスクリプト だけ見ときます
-----
integer is_open = FALSE;
default {
state_entry() {
llSetTimerEvent(0.3);
}
timer() {
if (is_open == FALSE) {
is_open = TRUE;
llSetLinkAlpha(2, 1.0, ALL_SIDES);
llSetLinkAlpha(3, 1.0, ALL_SIDES);
llSetLinkAlpha(4, 0.0, ALL_SIDES);
llSetLinkAlpha(5, 0.0, ALL_SIDES);
} else {
is_open = FALSE;
llSetLinkAlpha(2, 0.0, ALL_SIDES);
llSetLinkAlpha(3, 0.0, ALL_SIDES);
llSetLinkAlpha(4, 1.0, ALL_SIDES);
llSetLinkAlpha(5, 1.0, ALL_SIDES);
}
}
}
-----
0.3 秒毎に timer を起動します
-----
timer では is_open を調べ それによって 羽の透明度を切り替えることで 羽ばたかせています
-----
さて sworm の方ですが いつものように整形したものを以下にあげておきます
-----
次回以降 解説に入ります
-----
//
// File: swarm.lsl
// Date Author number of nodes
// 2007/9/24 walkinglint 164
//
// Swarm script
// by Apotheus Silverman
// This script is my implementation of the well-known swarm algorithm
// which can be found in numerous open-source programs.
// Due to the specifics of the SL environment, I have strayed from some
// of the traditional rules slightly. Regardless, the end effect is
// indistiguishable from the original algorithm.
// Configurable parameters
// Determines whether or not to enable STATUS_SANDBOX.
//
integer sandbox = FALSE;
// Timer length
float timer_length = 0.5;
// Die after this many seconds
integer kill_time = 300;
// Enables or disables schooling behavior
integer school = TRUE;
// Schooling comm channel
integer school_comm_channel = 9284;
// Schooling behavior update interval (should be a multiple of timer_length)
float school_update_interval = 2.0;
// How much force to apply with each impulse
float force_modifier = 0.7;
// How much force to apply when repulsed by another like me
float repulse_force_modifier = 0.86;
//
// How much friction to use on a scale from 0 to 1.
// Note that friction takes effect each timer cycle, so the lower the timer length,
// the more the friction you specify here will take effect, thereby increasing actual
// friction applied.
//
float friction = 0.45;
//
// How much to modify the rotation strength. Higher numbers produce greater strength
// Note that if the modifier is too small, the object may not rotate at all.
//
float rotation_strength_modifier = 2.8;
// How much to modify rotation damping. Higher numbers produce slower rotation.
float rotation_damping_modifier = 5000000.0;
//
// Does this object "swim" in air or water?
// 2 = air
// 1 = water
// 0 = both
//
integer flight_mode = 2;
// Maximum distance from spawn point
float max_distance = 2.5;
// How far away to scan for others like me
float sensor_distance = 5.0;
// *** Don’t change anything below unless you *really* know what you’re doing ***
float mass;
vector spawn_location;
float school_timer = 0.0;
vector school_modifier = <0, 0, 0>;
// Update rotation function
do_rotation(vector mypos, vector myvel) {
llLookAt(mypos + myvel, mass * rotation_strength_modifier, mass * rotation_damping_modifier);
}
// Collision function
collide(vector loc) {
vector mypos = llGetPos();
// Apply repulse force
vector impulse = llVecNorm(mypos - loc);
llApplyImpulse(impulse * repulse_force_modifier * mass, FALSE);
// llSay(0, "collide() - impulse " + (string)impulse + " applied.");
// Update rotation
do_rotation(mypos, llGetVel());
}
// This function is called whether the sensor senses anything or not
sensor_any() {
// Get my velocity
vector myvel = llGetVel();
// Apply friction
llApplyImpulse(-(myvel * friction * mass), FALSE);
// Schooling behavior
if (school && llGetTime() - school_timer > school_update_interval) {
llSay(school_comm_channel, (string)myvel);
school_timer = llGetTime();
}
// Get my position
vector mypos = llGetPos();
// Check for air/water breach
if (flight_mode == 1) {
// water
if (mypos.z >= llWater(mypos) - llVecMag(llGetScale())) {
// llSay(0, "collide() called due to air/water breach.");
collide();
}
} else if (flight_mode == 2) {
// air
if (mypos.z <= llWater(mypos) + llVecMag(llGetScale())) {
// llSay(0, "collide() called due to air/water breach.");
collide();
}
}
// Stay near spawn location
if (llVecDist(mypos, spawn_location) > max_distance) {
// Compensate for being near sim border
if (spawn_location.x - mypos.x > 100) {
mypos.x += 255;
}
// llSay(0, "collide() called due to too much distance from my spawn point.
// mypos=" + (string)mypos + ", spawn_location = " + (string)spawn_location);
collide(mypos - llVecNorm(spawn_location - mypos));
}
// Stay above ground level
if (mypos.z <= llGround(ZERO_VECTOR)) {
collide(mypos - llGroundNormal(ZERO_VECTOR));
}
}
default {
state_entry() {
llResetTime();
llSay(0, "Fishy spawned.");
// School
if (school) {
llListen(school_comm_channel, "", NULL_KEY, "");
}
// Sandbox
llSetStatus(STATUS_SANDBOX, sandbox);
llSetStatus(STATUS_BLOCK_GRAB, FALSE);
spawn_location = llGetPos();
// Initialize physics behavior
mass = llGetMass();
llSetBuoyancy(1.0);
llSetStatus(STATUS_PHYSICS, TRUE);
llVolumeDetect(TRUE);
// Initialize sensor
llSensorRepeat(llGetObjectName(), NULL_KEY, ACTIVE|SCRIPTED, sensor_distance, PI, timer_length);
}
collision_start(integer total_number) {
// llSay(0, "collide() called due to physical object collision.");
collide(llDetectedPos(0));
}
no_sensor() {
sensor_any();
}
sensor(integer total_number) {
sensor_any();
// Populate neighbors with the positions of the two nearest neighbors.
vector mypos = llGetPos();
list neighbors = [];
integer i;
for (i = 0; i < total_number; i++) {
vector current_pos = llDetectedPos(i);
if (llGetListLength(neighbors) < 2) {
// Add to list
neighbors = llListInsertList(neighbors, [current_pos], llGetListLength(neighbors));
} else {
//
// Check to see if the current vector is closer than the list
// vector which is furthest away.
//
if (llVecDist(mypos, llList2Vector(neighbors, 0)) >
llVecDist(mypos, llList2Vector(neighbors, 1))) {
// check against first list item
if (llVecDist(mypos, llList2Vector(neighbors, 0)) > llVecDist(mypos, current_pos)) {
llListInsertList(neighbors, [current_pos], 0);
}
} else {
// check against second list item
if (llVecDist(mypos, llList2Vector(neighbors, 1)) > llVecDist(mypos, current_pos)) {
llListInsertList(neighbors, [current_pos], 1);
}
}
}
}
//
// Process movement
// Apply force
//
if (llGetListLength(neighbors) == 2) {
vector neighbor1 = llList2Vector(neighbors, 0);
vector neighbor2 = llList2Vector(neighbors, 1);
vector target = neighbor2 + ((neighbor1 - neighbor2) * 0.5);
vector impulse = <0, 0, 0>;
if (school) {
impulse = llVecNorm(target + school_modifier - mypos);
} else {
impulse = llVecNorm(target - mypos);
}
// llSay(0, "setforce " + (string)(impulse * force_modifier * mass));
llSetForce(impulse * force_modifier * mass, FALSE);
}
// Update rotation
do_rotation(llGetPos(), llGetVel());
}
listen(integer channel, string name, key id, string message) {
list myList = llCSV2List(llGetSubString(message, 1, llStringLength(message) - 2));
if (llGetListLength(myList) == 3) {
school_modifier = <llList2Float(myList, 0), llList2Float(myList, 1), llList2Float(myList, 2)>;
school_timer = llGetTime();
}
}
on_rez(integer start_param) {
llResetScript();
//
// spawn_location = llGetPos();
// llResetTime();
//
}
}
-----
(続く)

同じカテゴリー(walking のスクリプティング講座)の記事
 プロフィール写真の表示に問題 (2009-11-30 20:55)
 ミニ太陽系 (2009-03-21 06:03)
 関数から文字列を返したら何か問題になる? (2009-03-18 18:02)
 llListFindList って型って関係ないんだったっけ (2009-03-18 14:02)
 夏時間(PDT)の実験 (2009-03-08 22:04)
 15パズルの作り方(その3) (2009-03-08 06:03)
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。