Thursday, October 24, 2013

Creator Resource - Land Impact: An explanation. Linking phantom and non phantom prims.

This tutorial is currently at Creator Resource - Land Impact: An explanation. Linking phantom and non phantom prims.



First time I wrote and taught this class, neither mesh nor Pathfinder did exist, and the way to keep phantom and non phantom prims linked was by using scripts, exploiting some bugs. However, Pathfinder put an end to one of those bugs and thus the "volume detect scripts", which were the ones used then, stopped working. I rewrote the class entirely to teach it again in summer 2012, and then rewrote it yet once more to adapt it to book-style. The text and images below are an extract from the first section of the "Blender - Modelling Basics 103" book that you may find, together with all the other Blender books, in my inworld store and also in my Marketplace store.

"WHEN MESH WAS ROLLED OUT TO THE ENTIRE SL GRID"
(A bit of history to know where we are)


Perhaps you remember, if you rezzed before the summer of 2011, that before mesh came to the grid, the land capacity (this is how many items a sim may contain) was simply measured in "prims." There was a direct relationship: your builds use N prims, whether they be boxes, spheres, torus or sculpts, so you're using a total of N prims of the land capacity.

It was August 23th, 2011, when mesh was rolled out to the entire Second Life® grid. As with every big change, problems and unexpected behaviours were bound to happen. Maybe you remember situations like when linking a torus to a mesh object, or dropping a script into a mesh object, it caused a dramatic increase of the "prim count" of the object.

What was happening here?
What happened was that, at the same time mesh was rolled out to the entire grid, the way the land capacity was accounted for also changed.

Why did it change?

Mesh objects could go from very simple shapes to very complicated objects, having a very different impact over the servers. It wouldn't have been realistic to assign a fixed "prim capacity" value to every mesh object. Simple objects would have been penalized this way, discouraging people from creating and using mesh.

What LL did was to set in place a new and more rational way of measuring the land capacity (for it makes us aware of the real impact we're having on the servers). It started being called "Prim Equivalence" (PE), and finally received the definitive name of "Land Impact" (which is the LI we often read).

Older builds that weren't linked to mesh at all, would have their LI calculated by using the equivalence "1 prim = LI 1". Objects that were linked to mesh objects would automatically "opt-in" to the LI calculations. That's why if we linked a box to a mesh, basically nothing happened, but if a torus was linked to a mesh, the LI bounced high, because under the new LI calculations, torus are expensive shapes.

At the same time mesh was rolled to the entire grid, another primitive property was added: the "Physics Shape Type". This property has three options: "Prim", "Convex Hull" and "None". They will be explained later. Right now, this is what's relevant: the existent prim builds had the property assigned to "Prim", and we heard that we should start changing linked prims to phantom by changing the "Physics Shape Type" to "None". But, in many cases, by doing this, we again had the LI of the linked object raising quickly and often above our parcel land capacity (thus causing the object to be returned to our inventory).

This happened for the following reason:

Only an object made of legacy prims (that is, anything that is not mesh) where all of the linked prims have "Prim" as their "Physics Shape Type" and not using normal/specular maps will be accounted for under the old "1 prim = LI 1" system. (July 2013)

Any other combination will be accounted for under the new mesh Land Impact (LI) system.

However, nowadays it is very difficult having a build made only of legacy prims, or a build made only of legacy prims where "Prim" is the "Physics Shape Type" for all of them. For this reason, it is very important to get acquainted as soon as possible to the mesh accounting system if we aren't already.

Even though the "None" Physics Shape Type allowed linked phantom and non phantom prims, builders continued to use an old trick, which was called "a volume detect script," to be able to have linked phantom and non phantom prims (which is essential when building houses, for example), in this way avoiding the need to switch the prims to "None", and the resulting huge increase in the LI.

And another big change was rolled to the grid, forcing builders to stop using this script, and using the new system. This change was Pathfinder.

While Pathfinder was still in the Beta grid, alarms were raised because builds using the "volume detect script" would basically make the region crash (making short a long story).

Because of this, when Pathfinder was rolled out to the main grid, LL also provided a solution to the big issue that would mean all the old content that would rez broken, as well as to the drawback of being forced to make builds with a huge LI if we were to keep linked phantom and non phantom prims, as a result of making the "volume detect" scripts no longer useful.

The solution they provided consisted of two main compromises:

  • Any existing build using the "volume detect" script would continue to be usable, as long as we don't unlink it and later re-link it. Once unlinked, we should use the new system. But at least, existing content would not rez broken.
  • The LI algorithm would be reviewed, so the complicated shapes (spheres, torus, sculpts...) wouldn't penalize our builds so much, should we want to use them mixed with mesh, or just because we need to use any Physics Shape Type other than "Prim".

If you're interested, this link will lead you to the server release when Pathfinder was rolled out to the grid (August 7th, 2012), and LL explains that the LI algorithm has been revised, and how:

http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_Server/12#12.07.31.262785

The news, back then, was very, very good :-) (we'll talk about it later)

So, knowing now where we are, and how we've reached this point, it's time to explain the mesh accounting system and the physics shape types. A good understanding of these concepts will help us create more optimized builds, whether they be mesh or legacy prims.

Optimized builds means creating less lag. We will always want this!

THE MESH ACCOUNTING: LAND IMPACT


As we've said, when mesh was rolled out to the main grid, a new system to account for the land capacity was adopted, and it was finally called "Land Impact" (abbreviated as LI). This system begins by calculating four values for any object, called weights, using only three of them to obtain the final LI. Those three values will show up in the mesh upload window.

You have probably heard about the weights:

Download Weight, Physics Weight and Server Weight. The fourth one would be Display Weight, but that one is not relevant for us here.

Let's talk briefly about these weights.

The Download Weight measures how much any object is going to impact the network side; simply put, it measures how much data needs to be transferred for the geometry of a shape. Complex objects have higher download weights than simple boxes, and even more significantly, big complex objects have a higher download weight than the same complex object... smaller.

Why would bigger objects have a bigger download weight than the same object, smaller? A bigger object is likely to be seen by more avatars at a further distance than a small one, so more bandwidth is required: more download weight.

This is why we have to keep an eye on this when we resize upward a mesh object (or, more generally, any object under the mesh accounting.)

Then we have the Physics Weight. This is a server side measurement that relates to how complex, in physical terms, an object is. As we will explore in the mesh upload window, indeed simple physical shapes will make this weight have lower values than more complex physical shapes.

Finally, we have the Server Weight, which is always, at least, 0.5 per object, and is related to how heavily scripted the object is going to be. That's why dropping many scripts into mesh objects could make the LI of an object increase under the mesh accounting.

Those three weights are calculated on LL's servers. To decide, then, what LI is assigned to an object, the greatest of the three values is chosen, and this value is rounded. This is how the final value for the LI is determined.

Let's study now what happens when two or more objects are linked.
By writing the following:

O(DW, PW, SW): LI

we mean in this book: "The object «O» has as download weight the value DW, as physics weight the value PW and as server weight the value SW, resulting in a Land Impact total of value LI."

For example:

My Box(1.2, 0.6, 0.5): 1

means: "The object «My Box» has a download weight of 1.2, a physics weight of 0.6 and a server weight of 0.5, resulting in a Land Impact total of value 1."

Using the nomenclature we've just established, we're now going to develop what happens when two objects are linked together.

Suppose we have the objects:

O1(DW1, PW1, SW1): LI1
O2(DW2, PW2, SW2): LI2

The linked object O1+O2 has as weights:

    Download: DW1 + DW2
    Physics:  PW1 + PW2
    Server:   SW1 + SW2

The resulting LI is not, necessarily, the same as LI1 + LI2. At times it will coincide, at times it will be less, at times it will be more.

Why?

Suppose we have, for example, two objects with weights and LI:

    O1(1.4, 0.2, 0.5): 1
    O2(1.3, 0.6, 0.5): 1

Since the LI for both is 1, we might expect the LI of the linked object to be 1+1, that is, 2. However, let's examine what happens to the weights when we link these objects:

    Download Weight  1.4 + 1.3 = 2.7
    Physics Weight   0.2 + 0.6 = 0.8
    Server Weight    0.5 + 0.5 = 1

The greatest weight here is the download weight: 2.7. This is rounded up to the value of 3. The LI of the linked object is 3. In this case, we would prefer to keep the objects unlinked, for the LI when they are separate is just 2, not 3.

Now let's see a different case:

    O1(0.8, 0.2, 0.5): 1
    O2(0.5, 0.6, 0.5): 1

The LI for both unlinked objects is 1. Again, we might expect the LI of the linked object to be 1+1, that is, 2. But let's examine again what happens to the weights when we link this object:

    Download Weight   0.8 + 0.5 = 1.3
    Physics Weight    0.2 + 0.6 = 0.8
    Server Weight     0.5 + 0.5 = 1

The greatest weight here is the download weight: 1.3. This is rounded down to the value of 1. The LI of the linked object is 1. In this case, we would prefer to have both objects linked, for the LI when they are separate is 2 instead of the more convenient 1.

To be clear, when we round a number, if the decimal part is greater than or equal to .5, the round is up, otherwise, the round is down.

As we've said, when this new accounting system was introduced, a new primitive property came holding its hand: the "Physics Shape Type" that we can find under the "Features" tab. Perhaps you've heard the words "Convex Hull" a lot... but what does that mean?

That's what we're going to study now.

We currently have three "Physics Shapes" for a given prim: Prim, Convex Hull and None. Together with the scripts usage, the physics is also relevant in terms of what makes the servers to be busy, therefore, it is important to understand the three types to correctly select the one that will minimize the cost for the server while performing the function that we need for it.

Physics Type: Prim

In this case, the physical shape is going to exactly match the visual appearance of the prim. If mesh, that is the custom shape we've defined for it.

If we're talking about a box, it's a pretty simple shape, and if it's a torus, we're talking about a pretty complicated shape, in physics terms, for the server. This is why, when making a torus to opt-in into the mesh accounting system, the numbers used to jump up quickly before LL modified the algorithm.

When we select this Physics Type for a prim, the physical boundaries of the prim will be the visible ones. We will fall through holes.

Physics Type: Convex Hull

Simply put, the convex hull of an object is an object without holes that wraps the original object. Convex Hull has a very specific meaning in maths, so although this definition is not 100% accurate, it allows us to understand, visually, what Convex Hull means.

In order to understand this, follow this procedure-demonstration:

  • Rez a torus
  • Resize this torus to X = 2, Y = 5, Z = 5
  • Rotate it to X = 0, Y = 90, Z= 0
  • Change the Hole Size to X = 1, Y = 0.25
  • Now walk on the torus until you fall through the hole, as the picture below shows:


Edit now the torus, click on the "Features" tab of the "Edit" window, and change the "Physics Shape Type" to "Convex Hull".

When you close the window, as soon as you move, the physics engine will push you outside of the torus (you may either fly or be pushed down). When you walk above the torus, this time, you will not fall through the hole, as the picture shows:


That's because now, for the physics engine, the torus is the convex hull of the visible torus: the torus, without holes (in a very simplified way).

Also the LI of the torus has raised to 2. That's because once we've changed the "Physics Shape Type" to other than "Prim", the torus is now evaluated under the mesh accounting.

As we can figure, the convex hull of an object with holes is lighter for the server, in order to calculate its physics impact. Convex Hull will define a simpler object in physics terms.

Physics Type: None

This simply will remove any physic shape from the prim. The prim turns into phantom, as we have seen before, with the advantage that they have absolutely no physical influence (which phantom prims still have!)

We've said in the first section of this book that on August 7th, 2012, LL completed a review of the LI algorithm and revised it accordingly, as explained here:

http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_Server/12#12.07.31.262785

What they say exactly is:

« Changed prim accounting for legacy prims which use the new accounting system.

All legacy-style prims have their streaming cost capped at 1.0 (except for sculpts, which will be capped at 2.0). This provides the benefit of not penalizing prim-based creators for optimizing their content by opting into the new system and will make the streaming cost more reflective of the true network cost of the objects.


This first part means that the download weight of legacy prims is 1.0, with the exception of sculpt prims, which have a 2.0 value for this, when they "opt in" to the mesh accounting system: this is, either we link them to a mesh, or we change the "Physics Shape Type" of just one of them to "Convex Hull" or "None", or we use normal/specular maps.

However, we have to keep in mind that the LI algorithm is always under review, so it shouldn't surprise us if at some time in the future a torus, or other shapes, may have a bigger LI than 2 when in the mesh accounting system. The physics could have some relevancy.

The bottom line is, always keep an eye on the way the weights and the total LI behave.

Then, LL continued saying:

Server cost will be adjusted to

MIN{ (0.5*num_prims) + (0.25 * num_scripts), num_prims }.

This preserves the current value for unscripted linksets and reduce the cost for linksets containing fewer than 2*num_prims scripts. It provides the benefit of rewarding creators for reducing the number of scripts in their objects. »


What the formula means, in very simple terms, is that a low scripted object in the mesh accounting system will not be penalized, as it was before Pathfinder was rolled to the grid.

TECHNICAL NOTE: WHEN SCULPTS MAY "ABSORB" THE LI OF BOXES


As we've explained before, since we can no longer use the "volume detect" script trick to link phantom and non phantom prims, we need to change the Physics Shape Type of the prims that should be phantom, to "None". After all this discussion, is clear that the build will opt into the mesh accounting system as soon as we do this, so any sculpt that forms part of the build will contribute with an LI of 2. This LI 2 is separated as follows:

    Download:  2 (Max)
    Physics:   Might be around 1.8
    Server:    0.5

Let's call this sculpt, S, so using the nomenclature from before:

S(2, 1.8, 0.5): 2

Knowing that, under the new accounting, given two objects O1 and O2 defined by their weights with the nomenclature we established:

O1(DW1, PW1, SW1): LI1
O2(DW2, PW2, SW2): LI2

the linked object O1+O2 has as weights:

    Download:  DW1 + DW2
    Physics:   PW1 + PW2
    Server:    SW1 + SW2

we can benefit from this, to be able to add one or more "low weight" prims (e.g. boxes) to the object without increasing the LI, when linked under the mesh accounting system. We can do this whenever one sculpt should be "phantom" (Physics Type: None) and linked to a build.

What happens now when we link this sculpt to a box?
Let's call this box B1. How are the weights distributed in a box?

We can know this by clicking "More info" in the "Edit" window when we inspect/edit an object:


and so we can read, under the "Weights of Selected" section of the little popup that shows, that our box B1 has the weights distributed as:

B1(0.1, 0.1, 0.5): 1

NOTE: If the actual weight is calculated as less than 0.1 (for example, 0.09), the viewer will round it up to 0.1 to show the information using only one decimal. But this means that, for example, two weights of value 0.05, that will show as 0.1 in the viewer, when added, will not show as 0.2... but as 0.1! (the result of adding the two 0.05).

What happens to the LI when we link S and B1 to obtain S+B1?
We saw that we have to add the weights:

    Download:  2 + 0.1 = 2.1
    Physics:   1.8 + 0.1 = 1.9
    Server:    0.5 + 0.5 = 1

and then round the greatest value, which here is 2.1. That gives us a value of 2 for the LI of the linked sculpt and box.

This is interesting. So the LI of S+B1 continues to be 2.
What if we add a second box, B2?

We solve this by adding the weights again:

    Download:  2.1 + 0.1 = 2.2
    Physics:   1.9 + 0.1 = 2
    Server:    1 + 0.5 = 1.5

then again we round the greatest value, which here is 2.2, and so that gives us a value of 2 for the LI of the linked sculpt and two boxes.

The practical effect is that the very low weight a box has, is being absorbed by the (relatively) high download weight of the sculpt prim. So, although sculpt prims are a bit penalized in the new system, we can use as many boxes as we need, without a penalization, for they will be "absorbed," in a way, within the LI of the sculpts.

IMPORTANT: If our sculpt prim should be phantom, then set its "Physics Shape Type" to "None". That will make the physics weight of such sculpt to be 0, and so this 0 is what will be added to the rest of the physics weights of the other prims in the linked set. Of course, use the same reasoning for non sculpt prims :-)

Sunday, October 13, 2013

A ladder to nowhere

This post is my contribution to: The Writer's Block, Chapter Five

As a curious person about anything that has to do with my fellow humans' behaviour, exploring social ladders isn't an exception of what tickles my interests. "Climbing the SL social ladder" was calling me.

I first thought of writing about the dynamics: the people that are up, the people that are down, the different degrees among "down levels". It would be difficult not to mention how the ones being on top of the ladder use their position as a soapbox for their personal life, preferences or witch hunts. How they turn into our Gods to follow, our Example in Life to imitate. It would also be difficult not to talk about how the ones being down would kiss ass until having sore lips, in their attempt to climb steps and receive kind words from the Gods, kind words they could rub on your face if you're on a lesser level. "Look at me, the Gods talk to me and not to you! You're nobody!" It would be mandatory to highlight the hypocrisy and cowardice of those being down, which would never dare contradicting the Gods, even if they do not agree with said Gods, but attack all the other nobodies they don't agree with that belong to a lower level in the ladder, to show they have "an independent opinion". Sweet smiles on your face and knives flying on your back.

However, me being a nobody, I realized I would be soon pointed out like being a jealous person, having secret intentions, using this as a chance for my own climbing up the ladder, and many other spurious interpretations from my true intentions, which are merely observing and describing what I see. So I decided to leave that train of thought, and I tried to explore other aspects.


I then thought about how those that are on the top of the ladder decide the trends, even if the trends are stupid. It doesn't matter: everybody being in a lower step in the social ladder will bleat and praise how good the trends are. How those that are on top draw the lines that say "this is right, this is wrong", and never dare having a different opinion or make questions about how they arrived to that conclusion. Never ask who gave them power to draw those lines. It would be also impossible not to mention how those that are down in the ladder drool to be on top, so they are the ones with the self-adjudicated privilege of drawing their own lines.

But trends are a matter of taste, "right and wrong" they'll tell you "this is what the majority thinks", as if the "majority" being a mass could never be wrong, and again, I am a nobody. So I realized I would have some more dozens of interpretations from my words that would never be what I wanted to say, and likely nobody else would even bother in asking me what I really meant.

And so I kept thinking what else I could explore, and got to the conclusion that the only way of safely talking about climbing the SL Social Ladder, is not to talk about it at all. In the tale, the kid pointing out that the Emperor was naked, was considered wise, but in real life, those that point out that the Emperor is naked, are the first ones to be burned.

Credits

Clothes and shoes: Teefy, Baiastice, Gos, Indyra, Milk Motion, Valentina E.
Hair: D!va, Truth, Monso
Skins: Glam Affair, Belleza
Ladder & Column Photo Prop: My own (Black Tulip)

Saturday, October 5, 2013

Creator Resource - Animated Water Texture in GIMP

This tutorial is currently at Creator Resource - Animated Water Texture in GIMP.



GIMP version used in this tutorial: 2.8.2
Different versions to the major 2.8 release may have the filters and options placed and named differently. You'll have to check where the options are in that case in your GIMP version, for they may not correspond exactly with the ones explained here.

What you'll learn here:


This tutorial is intended for those having the following minimum knowledge of GIMP:

  • Working with layers
  • Using the grid/guides
  • Using filters

If you've never used the grid/guides, nor filters, but you do know how to work with layers, you may still follow this by making sure you follow the exact steps indicated. If you have no knowledge about working with layers in GIMP, consider reading some information about and practicing prior to follow this :-)

Also, this tutorial gives a lot of information and alternatives for you to try in each step. If this confuses you at first, follow the tutorial only with the first given alternative per section, temporarily ignoring all the "asides", "notes" and "you can also try", and once completed, then read all the other information on how to make variations, seamless base textures, seamless animations... to make the best of it.

This said, let's first explain the idea after the effect we want to achieve. We're going to create a texture that, when animated by a script in SL, will look as follows (the whole animation may take some seconds until downloading complete to your browser's cache):


(Please, check this document for the details about how to use a script for this, not creating server side lag!)

Because of the way the texture is animated, it means that we'll have to create several frames, and then merge all of them together in the same texture. The reason for the latter is that the required scripting function demands the texture to be animated to be just one texture: if we want to animate frames, we have to put them all together in the same texture.

The process of merging all the frames together to create a single texture containing them all, will be explained by the end. We are going to focus first in creating the animation frames separately, and for that, the process will be creating a base frame texture, and then using a GIMP filter that will create all the other frames.


Creating the Base Texture


Let's begin by creating a new image, of size 512x512 pixels:


We'll be working here the base frame.

Now, a little bit of useful information about GIMP: under the "Filters: Render" menu, GIMP has several choices that will CREATE a texture, and we will be able of modifying some parameters, that will change aspects of this texture.

For example, "Filters: Render: Clouds" contains a few filters that will generate cloud-alike textures:


And after exploring the filters under the "Filters: Render" menu, we find one that at first, doesn't look like what we would be after. It's called "Lava" in the end! Lava doesn't suggest water :-)

So we go for "Filters: Render: Lava", and GIMP presents us the following window:


Let's accept for now the default parameters and observe the result, which when using this filter, is always produced on a new layer if the "Separate layer" box is ticked (default choice):


Well, interesting result, but how this could resemble to water in any way? Let's explain the main parameters we can modify in this filter, and we'll begin noticing the similarities.

The first parameter we find for this filter is "Seed". This "Seed" parameter is an initial value that is taken by the generator, influencing the distribution of the segments. The patterns are generated pseudo-randomly. The same seed number may yield different segment distributions each time (like the picture below shows), but giving "Seed" a different value each time, we'll sure obtain different patterns for our base texture.


Next we find the "Size" parameter. "Size" has an influence over the length of the "lava segments". Too high a value and we'll have here a few lines with long almost squared turns, which will not be useful for our effect.


Useful values for us will be between 5 and 15. However, be aware that when size is too low, the generated layer may have some "alpha gaps", noticeable only when you copy it and paste somewhere else. Something you can do is creating a background layer with a color the closest possible to the background lava color, below the lava layer, and then merge the lava layer down to this solid background. The alpha holes will be covered this way.

Now we find "Roughness". The "Roughness" parameter influences over the size of the "waves" that separate the "lava segments".


At this moment, the similarities with water are more apparent. If only we could easily change the colors used in this "Lava" filter!

Roughness is set to 27 here. Nice lava-water base texture!

Wait... We can, indeed, easily change the colors :-)

We can, because the next important parameter that the "Lava" filter gives to us is... the color gradient we want to use for it! This is, we're not constrained to using only the gradient generating the lava texture. We can use other gradients. Like for example, variations from blue to green, which is a color we'll likely see in water :-)

So, for example, using the following values:

Seed       23
  Size       11
  Roughness  27

we can now obtain the following results, by simply selecting a different gradient, when we click for the "Filters: Render: Lava" window:

"Blue Green" Gradient

"Caribbean Blues" Gradient

"Horizon 2" Gradient

We can of course use gradients that have nothing to do with water, for creating "specials":

"Cold Steel" Gradient

and we can even create our own gradient, then use it here.

Then we may continue working on this generated texture, for a better base water texture, but for the purposes of this tutorial, we'll work with a base texture obtained by using the "Filters: Render: Lava" filter with the following parameters:


Now, in order to save this file, let's first remove the transparent background layer that remained when we started creating a new image:


We have to click to select it, and then delete it. We know it's the selected one because it will be highlighted in blue. It's obvious in the screenshot above that the transparent background is not the selected layer :-)

Save your work in your hard drive with a name like "Water_BaseTexture_Test.xcf"


Seamless water for sliding water effects


This texture is obviously not seamless, so it would not be suitable to be used in sliding water effects. If you want to make it seamless, this is very easy in GIMP.

First duplicate the generated layer, to keep a backup of the non-seamless one:


Now, select the following option, "Filters: Map: Make Seamless", and there we go!


Seamless base texture, or that can directly be used in sliding water effects :-)


Making GIMP to generate the animation frames, and learn also how to make the animation to be seamless \o/


This is the fun step. We're going to tell GIMP "animate this!" and it's going to say "Yes Miss" :o) (or "Yes Mr", or whatever else you prefer.)

Let's suppose we'll be creating a 16 frames water animation (the 16 frames because of a 4x4 distribution over the texture), and give a first try to "Filters: Animation: Waves...", by only changing the number of frames to 16, leaving the rest set to the default values:


This creates a new GIMP-document containing the 16 frames, each one in a different layer:


Save this new GIMP-document as "Water_WaveAnimation_16frames_Test.xcf" before continuing.

It would be nice if we could first display the animation somehow, before doing more work. We can, indeed, do this. All we need to do is clicking the "Filters: Animation: Playback..." option, which will open the animation player in a new window:


From there, we can play the animation, stop it (clicking on the "Play" button, which looks pressed when the animation is running), and close the window if we like the result. For the purposes of this tutorial, we like the result :o)

Of course, once you get the hang of this, play with the amplitude and wavelength values, to obtain different animations (in the following picture, amplitude was set to 20 and wavelength to 15):


This is not the only animation effect we may use for water. We can also try our hand with "Filters: Animation: Rippling...", which produces a rippling effect instead of waves:


This could be good for a pool

Careful: If you give too much of a high value to "Rippling Strength", the effect, when played, will look psychedelic to say the least :-)

Try also with "Smear" for the "Edge behavior" parameter if you use "Rippling".

Historical note: When I started digging into the GIMP filters to create animated water, my base texture was a colored render-plasma layer that I first distorted with iWarp and later blurred with Gaussian Blur. Then I used Rippling to animate it. It looked weird, but convincing, for sort of plasma-witches-cursed-soups. You may want to give this a try too :-)

NOTE: Seamless animation for rippling, so I can tile several prims with it? Can I haz?

Of course you "can haz" :-)

What you should do, is make each frame seamless on its own. This is as simple as selecting one layer in the layers window, then applying the "Filters: Map: Make Seamless" function. Click to select next layer, and again, "Filters: Map: Make Seamless". Rinse and repeat, until you have them all :-)

BONUS: If you do this in the "Waves" kind of animation, you'll be able to seamlessly tile several prims with waves, for the way the seamless filter works in GIMP, will add a quarter of a wave in each corner. Way cool!



Putting the frames together to create a suitable texture to be used in SL


Once we have all the animation frames generated by GIMP, we have to put them together into one single texture that will be later used by a script.

As we know, textures in SL have its size limited to 1024x1024 pixels. The animation we've created has 16 frames, that can be distributed as 4x4 horizontal-vertical cells over this 1024x1024 horizontal-vertical pixels. This means that the size of each frame has to be:

Horizontal  1024/4 = 256
  Vertical    1024/4 = 256

So the resolution of each frame has to be 256x256, so we can put them all together on a single 1024x1024 texture.

Let's save our "Water_WaveAnimation_16frames_Test.xcf" with a new name, for example, "Water_WaveAnimation_16frames_Test_256x256.xcf", and close the previous one, "Water_WaveAnimation_16frames_Test.xcf" (We want to keep copies of our work at better resolution, in case we need to redo it. If we go from high resolution to lower resolution, we will not lose detail, but if we go from lower resolution to high resolution, we will lose detail!)

Now, in this "Water_WaveAnimation_16frames_Test_256x256.xcf", we select "Image: Scale Image..." from the menu, which will show the following window:


We type 256 in X, and since the chain icon (next to the X Y edit boxes) is activated, that will calculate 256 automatically for Y as we hit TAB to exit the X edit box. Then we accept, and GIMP will resize the image to half its size in both X and Y, which means, all the contained layers will be scaled down too. When we have this, we save this image and close it :-)

Let's think now in how to compose the final texture that we will upload to SL. First, create a new image, 1024x1024 this time (the size of the definitive texture) and save it as "Waves_Test.xcf" immediately (so you can comfortably save as you go hitting CTRL S)


Now, over this image, we have to put together all the frames, by placing them in a specific configuration:


At first glance, it looks like it's going to be difficult to achieve that exact positioning of the layers. Nothing further than the truth, though. GIMP allows us two ways of achieving exact positioning of our layers over the image. One of those ways is by using guides, the other way is by using a grid. Both ways have the same in common: we can create "lines" over the image whose only function is to "attract" the layers if we move them close to where those "guides" are. The layers will snap into place easily.

So we're going to study how to create an arrangement of guides that could serve us, and we'll also learn how to do this with GIMP's grid.

Create another 1024x1024 image where we'll study this. We don't need to save this one.

Method 1: The Guides

First, for the guides. Make sure that the "View: Show Guides" and "View: Snap to Guides" options are ticked. Now click "Image: Guides: New Guide (by Percent)", which brings up the window:


If we accept, we'll see the guide added to our layout:


If we think in our 4x4 required arrangement, we see that we will need to place three guides horizontally, another three guides vertically, having the following percentages each: 25%, 50%, 75%

(Why those percentages? Because there are 4 frames horizontally, 4 frames vertically, so we need in each direction guides that give us the exact position for the first 1/4 of width/height, the second 1/4, etc. When we divide 100% by 4 we get 25%, which means, the guides have to be separated that percentage, so the 4 frames fit.)

After placing the guides, by clicking all the times the "Image: Guides: New Guide (by Percent)" option and then selecting the 25%, 50%, 75% percentages in both horizontal and vertical, our layout looks like:


Now do the following experiment to understand how layers are "attracted" to the guides when we move a layer close to them. Create a new layer in the picture, with white background:


Move the layer close to the guides in the picture below. Because the mentioned option before, "View: Snap to Guides", is ticked, the layer will snap exactly to the corner:


Delete this layer if you wish.

Method 2: The Grid

If you don't know how to remove the guides from your layout, then close without saving the example we've done with the guides and create yet another 1024x1024 pixels image to make our grid practice. After completing this tutorial, you can head over the GIMP documentation page to learn about manipulating guides in GIMP. If you know how to remove the guides from your layout, then simply remove the guides we've added in the previous method-explanation :-)

Make sure that the "View: Show Grid" and "View: Snap to Grid" options are ticked. Now click "Image: Configure Grid...", which brings up the window:


Since we want to have a 4x4 grid, that means we have to divide our 1024x1024 pixels in 1024/4 x 1024/4, this is, 256x256 pixels areas, so we type 256 and 256 for width and height, and our layout changes to:


We see that this option has drawn a grid of lines on our image. However, those lines aren't visible pixels that will be saved in our image. Those lines play the role of the guides we've used before. By having "View: Snap to Grid" ticked, when we move our layers close to them, the layers will snap to the grid lines, exactly as we've seen happen with the guides.

Close this practice image and let's go back to "Waves_Test.xcf"

Now either prepare a grid of guides, as explained, or set up the 4x4 grid. Next is importing as layers all the frames of the animation, already resized to 256x256 pixels. We do this by following the "File: Open as Layers..." option from the menu, and selecting the "Water_WaveAnimation_16frames_Test_256x256.xcf" file we saved before.

This will open the 16 frames as separate layers in our image:


Now select the layer named "Frame 1" in the layers stack. Move it to the position it should occupy, according to the frames distribution image that we've studied before, so the final result is:


Now select the layer named "Frame 2 (replace)" in the layers stack, and move it to its position:


Same for layer "Frame 3 (replace)":


and we continue until all layers are correctly placed over the texture:


Don't forget to save it!

Finally, we have to save our image. For this, we first make sure we've saved the .xcf file (CTRL S). Now, saving files in GIMP as image files (PNG, GIF, JPG, etc.) is different since the 2.8 version.

First, select "File: Export to" from the menu, locate where in your hard drive you want to save the file, and type a finishing .png as extension, to tell GIMP that we want a PNG file. This will export the PNG file with alpha channel. If our texture shouldn't have alpha channel (transparency), then we have to do one more step.

This step would be open the PNG image we've just exported, then click Image: Flatten Image so the alpha channel is removed, and then "Export to" again over the same image. It's cumbersome, but it's the way it's done now >.<

If you don't know if your texture should or should not have alpha channel, this is a simple rule of thumb: if the image has no transparent visible pixels, then it should not have alpha channel, and so you have to remove it by flattening, and export again it as we've explained :-)

Log into SL, go to the "Build: Upload: Image" option, select the texture on your computer, and upload it. Congratulations! Your texture is inworld and ready to be used. Now that you have this texture, head over the "Creating Zero lag animated water" tutorial, to learn how to script this in SL, so you have your finished water objects... not creating server side lag!

NOTE: Now that you've learned the hard way, this is, importing all the layers, using the grid, or the guides... You can benefit from a script created by Pedro Oval, that you can install in GIMP, and will help you converting all the layers to a texture suitable for being animated under a script in SL.


Extra: How to make an animated GIF of our water texture, to demo it in Marketplace


This is going to be easy :-)

Open the file having each frame as a separate layer, "Water_WaveAnimation_16frames_Test.xcf" from our tutorial. Then select the "File: Export to" option. Look where in your hard drive you want to save the file, and make sure you type a finishing .gif as extension, to tell GIMP you want a GIF file. When you accept, the following window will show:


Make sure you tick the "As animation" check box as well as the "Loop forever" one, add a signature if you wish in the "GIF comment" edit box, and hit "Export". Your GIF file with the animation is ready.

IMPORTANT: Since it's easy to convert an animated GIF to layers and get this way all the frames, when you upload an animated GIF to Marketplace, to show how your animated water looks like, make sure that all the frames are watermarked visibly, with big "Sample" words and your sign on it. Watermark them so a not-too-lazy person would require work enough to remove it as to prefer just not bothering :-)

-- Auryn Beorn

Creator Resource - How to create Zero lag Animated water

You can find this text also in notecard format as a part of the following free package I have in Marketplace: How to create Zero lag Animated water. That little box of goodness contains all the scripts you need, as well as a couple of full permissions sample water textures :-)

If you haven't read it yet, you'd be interested in checking out the "Low lag scripts for builders" class. If you want to learn the basics on creating animated water textures, check out this tutorial, which explains how to make it in GIMP.

IMPORTANT: You do not need to save the sample textures shown here and upload them to SL. They are included in the free package linked above :-)

Table of Contents



Please, share this box for free!


Creating animated water in SL is a very basic skill that, sadly, the way it's usually performed, contributes in increasing the server side lag. This is by not being aware of the following fact: the scripts to animate water can be removed. Instead, they are left in the prims, and thus, SL has plenty of animated water with (unnecessary) scripts which add to server side lag.

For this reason, I've developed this document, that will teach you how to create zero-lag animated water and put together several animate texture scripts that include a self delete function.

For the same reason, I want that the content of the folder is freely distributed, all together. Please, share with your fellow builders all the contents of this folder, and tell them to do the same.

If you have questions, please feel free to contact me asking about how to do it.

The following contents are allowed to be distributed for free: (this refers to the contents of the package you'll find in Marketplace)

This documentation:
[Black Tulip] How to create ZERO LAG animated water

Scripts:
[Black Tulip] Anim - Smooth & Self Delete
[Black Tulip] Anim - Rotate Smooth & Self Delete
[Black Tulip] Anim - Cell Animation & Self Delete
[Black Tulip] Anim - Stop Animated Texture & Self Delete

Sample Water Textures:
[Black Tulip] Sample Water - Seamless (Sliding)
[Black Tulip] Sample Water Cols: 3 - Rows: 4 (Cell Animation)
[Black Tulip] Sample Water Cols: 4 - Rows: 4 (Cell Animation)

Thanks for your concern in creating a prettier SL with less lag.


Creating animated water on SL: The main idea


The effect of water in SL is usually achieved by using, what we call "animated water." Then particles could also be used to enhance parts like where the water falls against the ground or rocks. For the purposes of this document, which is to create a simple guide for builders creating ZERO LAG animated water, we will focus in using animated textures.

We may use two specific ways of animating textures in order to get water flowing (rivers/waterfalls/etc) or waving/rippling water (pools/ponds/etc). Both of these ways require a script to start the animation for the texture, and that is true, but, what perhaps you didn't know is...

... that once you have your animated prim, you can delete the script from the primitive.

What do we achieve with this? We achieve not increasing the server side lag due to the existence of scripts inworld. Animated water does not need that scripts remain in the prims: delete them.

So this will be the general procedure that we will follow in order to get a primitive with an animated texture to emulate running water.

  • Build your primitive, resize, rotate, etc
  • Apply on it the water texture you want for it
  • Drop one of the scripts from this box, depending of the specific kind of animated water we want


Creating animated water on SL: The details


Make sure of being at a place where you can rez.

Now rez a box. For this you can click the "Build" button at the bottom of your viewer or, alternatively, click CTRL 4. Either case, the edit window will show up, and the mouse pointer will change its icon to a magic wand. Click on the ground, and you'll see the box appearing (if there's lag, this could take a few seconds to appear.)

Now, under the "General" tab of the edit window, give this box the following name:

My Water Prim - Test

Depending on the type of water, you will need one or other texture, and also one or other script.

If you want water flowing, as you would expect it from a waterfall or a river, you will need to use an appropriate texture and the script to make the water to slide. This is explained under the "Animated Water - Sliding" subsection.

If you want water waving, or rippling, as you would expect it from a pool or a pond, you will need to use a different kind of texture and another script to make the water to "wave" or "ripple". This is explained under the "Animated Water - Ripples, waves (Cell Animation)" subsection.

Both subsections explain you how to tweak the corresponding script if you wish to change the speed in the animation, as well as the number of frames for the "cell animation" case.

If the script does not compile... don't drop it in the prim!

You will know this because you will see a "Syntax Error" appearing. Consider asking for help in groups that offer assistance to creators, if you don't know how to fix this.


Animated water: Sliding


Edit your "My Water Prim - Test" box. Click the "Texture" tab of the edit window and drop in here the "[Black Tulip] Sample Water - Seamless (Sliding)" texture. This is a seamless texture that will look good no matter which direction you want the texture to flow: you changed that by changing the texture rotation to 0, 90, 180 or 270 degrees.


Click now the "Content" tab of the edit window and drop the "[Black Tulip] Anim - Smooth & Self Delete" script inside the primitive. It will animate the texture and then self delete.

If the water is not flowing in the direction you wish to see it, proceed this way:

  • Click the "Texture" tab of the edit window.
  • Change the number in the "Rotation" edit box. It's 0 by default in boxes.

Interesting values here are: 0, 90, 180, 270

When you have the one you like, close the edit window.

Water is flowing too fast/slow. How can I change this?


Open the "[Black Tulip] Anim - Smooth & Self Delete" from your folder in your inventory.

Look for the line saying:

float   rate = 0.025;       // Rate - Low values: Slow - High values: Quick

Change this 0.025 to any other number of seconds you wish. 1.0, 2.25, 0.53...

Click the "Save" button or hit CTRL S to get the script to save and compile. Once you get the message telling you that the script has compiled, drop it inside the primitive. This will refresh the rate of the animation and self delete again the script.


Animated water: Ripples, waves (Cell Animation)


Edit your "My Water Prim - Test" box. Click the "Texture" tab of the edit window and drop in here the "[Black Tulip] Sample Water Cols: 3 - Rows: 4 (Cell Animation)" texture. This is a texture containing 12 cells, distributed in 3 columns and 4 rows, that make a total of 12 frames that will be played one after the other to create the illusion of the water rippling.


Click now the "Content" tab of the edit window and drop the "[Black Tulip] Anim - Cell Animation & Self Delete" script inside the primitive. It will animate the texture and then self delete. You can now close the edit window.

Water is flowing too fast/slow. How can I change this?


Refer to the previous subsection - Procedure is the same here.

My texture has a different number of columns/rows. What do I have to change in the script?


Open the "[Black Tulip] Anim - Cell Animation & Self Delete" from your folder in your inventory.

Look for the lines saying:

integer columns = 3;
integer rows = 4;

Change those numbers to the number of columns and rows your texture has.

Those numbers can't contain decimals. An example, the following is NOT correct:

integer columns = 3.24;     // This is WRONG
integer rows = 4.75;        // This is WRONG

but the following:

integer columns = 4;
integer rows = 5;

is CORRECT (and what you would change this to, if your texture had 4 columns and 5 rows - which total 20 frames for your animation.)

Click the "Save" button or hit CTRL S to get the script to save and compile. Once you get the message telling you that the script has compiled, drop it inside the primitive. This will refresh the rate of the animation and self delete again the script.

There it is another texture in this folder to help you in practicing with this:

[Black Tulip] Sample Water Cols: 4 - Rows: 4 (Cell Animation)


This one has 4 columns and 4 rows. So you should change the numbers in the "[Black Tulip] Anim - Cell Animation & Self Delete" script to:

integer columns = 4;
integer rows = 4;

save the script, and then drop it into the primitive.


Important notes


NOTE: As of 2012-05-29, there's still a bug that will stop the animation on a copied primitive by using the SHIFT COPY technique to duplicate a primitive. You may use a workaround here: Take a copy of your scriptless animated primitive into your inventory, then rez a new copy. The animation is preserved on rez if you have removed the script to activate it.

More information, here: http://jira.secondlife.com/browse/SVC-3925

NOTE: To animate water, you won't need to rotate this texture as it's animated, usually, but to complete the collection of scripts with the most used animated texture effects, this box also contains a script named "[Black Tulip] Anim - Rotate Smooth & Self Delete".

NOTE: If you want to STOP the effect of animating a texture, use the script named "[Black Tulip] Anim - Stop Animated Texture & Self Delete". Edit the prim, drop the script. It will stop any texture animation that could be running.

NOTE: To STOP all the animated textures in a linked object, use the "[Black Tulip] Anim - Stop Linked Animated Texture & Self Delete" script instead.


All the scripts in this box self delete. Please USE and SHARE them!

-- Auryn Beorn

Tuesday, October 1, 2013

Sweet Snakes

I had this in drafts for a month now. This question, and picture, reminded me that I had to finish it. The post could have died out of boredom in drafts, and I wanted to bring it up.

IMAGE: Sweet Snakes. Are you sure that you can really tell who they are?, in Flickr.

A few months ago, while performing my usual "profile perv" routine for every living being in the same sim as me, it was frequent to read some copy-pasted texts that made me "facepalm" to say the least. (Note: Profiles can't actually be "perved" since they are public, and are meant to be read. Whatever you don't want that others read, don't write it there :-))

"What texts?," you may wonder.

One is an ASCII art of a little puppy with a text such as "Copy this in your profile if you're against animal cruelty", another is a full pick titled something like "Post this if you're against abuse," being the text I've found as follows (I've respected the original writing on purpose):

The 14 year old girl holding hands with her 3 year old son, the one you just called a slut... She was raped at the age of 11. The girl you just called fat...shes overdosing on diet pills. The girl you just called ugly... she spends hours putting makeup on hoping people will like her. The boy you just tripped... he is abused enough at home. See that man with the ugly scars... he fought for his country. That guy you just made fun of for crying... his mother is dying. Put this as your status if your against bullying. I bet 95 percent of you wont re-post this, but i'm sure the people with a heart and backbone will.

Moving, right?

Call me cynical if you wish, but those lines above are prefabricated lines that are good for nothing except to feel good about ourselves. Don't get me wrong here. The cases described are for sure situations that we should avoid, but the stories are so easy to think of, that none of us would give a deeper thought about what could constitute abuse after reading that text, and that defeats the point of raising awareness against abuse.

Not to mention that, of course, copying that text sure proves that I am quite of a compassionate and understanding person, specially about abuse cases. Personally, if I was being abused, I would feel that text as an insult, to both my situation and my intelligence. The only you prove when you copy that text is that you know how to copy/paste. If you really believe it proves you are a good person, let me add that it only shows how easy is to manipulate you through your feelings. In any case, I would raise an eyebrow. Abusers are the quickest in pointing fingers to anybody else.

Likely, you're thinking that I'm having more than a sharp tongue and an excess of sarcasm case today. That could be true. Now, think about this: we all hold by the highest principles when we are not the person having a problem, or could have a problem by defending the abused one. Will you continue holding by those principles and being that compassionate, in situations where defending the abused one could make you to lose your job, your family, your properties, your health, your friends...?

Don't rush into saying "yes". I have to see what you will do in situations like some I've known about.

For example, I remember the case of a guy that I'll call Norman here. He was working in his father in law's company, managed by the elder son at that time (let's call him Robert). The real reason, as I knew later, trying to understand why Norman put himself under all that pressure, is that the in law's have asked him to investigate what was really happening in the company, for they were afraid that Robert was proceeding with some kind of fraud.

Robert wasn't naive and he figured out what his parents were up to, when they demanded the incorporation of Norman in the company. To make short a long story (since I also don't remember all the details well), this is what happened:

  • Robert manipulated people in the company to block Norman's ability to work.
  • Robert played several legal tricks to fire Norman.
  • People in the company knew they were doing wrong, but because they feared losing their jobs, they played as Robert's pawns attacking Norman.
  • Norman could complete his investigation anyway. As the truth of the size of the fraud was closer to be revealed, his in-law's became emotional and gave Robert all the legal power to hit Norman within the company.
  • The extent of the fraud that Norman found out about was appalling. The authorities went against Robert because of another fraud that wasn't what Norman was investigating, but financed with that money anyway.
  • Charges and a high fine were filed against Robert. The company closed. All the people that collaborated in helping Robert, the abuser, because of their fear, ended up losing their jobs when the economical crisis started to hit the country hard.
  • Norman's wife, unable to believe what her parents had done, cut the communication with them. They, in exchange, disowned her, for not divorcing from Norman, "who is guilty of the closure of the company and the problems your brother Robert has now".

Not bad. The abused is bullied and portrayed as guilty of what happened. If you ask me, I don't know what I would do unless I live that situation. Yes, sure, "you're against abuse". Does that mean you wouldn't let Robert to manipulate you through your fear? Let me doubt it.


This case is likely a not so subtle abuse case. There are hostilities in the open. And still, it shows that in difficult situations, most people are cowards and consent and favor abuse in hopes that it will not turn against them. If this happens when abuse is so clear, what would you expect when the abuser is a sweet snake? Let me go for another story.


Sarah (let's call her that way) was very timid and fearful of people when she started working in a certain advertising company. She was warmly welcomed, and soon she felt at ease, focused, and making a good job. She tried not to enter in disputes and to be fair when colleagues argued, asking to each side of the confrontation to see the situation with perspective. When arguments were up, she never took a stance for anyone, to avoid being dragged into the "he said, she said, you said" office drama dynamics.

There were a couple of colleagues that used to be always arguing with almost everybody (Martin and Leanne), because reality didn't fit into their strict vision of world. They were often right, but they were also often a source of conflict because of their attitude, and Sarah was always in the middle trying to mediate and achieve some peace. Since they were good in their job, and Sarah was always there to mediate and avoid conflicts, the company had no issues in keeping them.

After four years, Sarah's job was often praised, as well as her pacifying skills. One year after, another girl joined this company. Let's call her Vivian. Vivian wasn't specially skilled, but she was very sweet and kind, and because of her youth, Sarah thought she'd help her acquire the skills that Vivian was obviously lacking, mentoring her. Sarah always welcomed new people at work.

It was first Martin who started complaining about Vivian. Apparently, Vivian was making a lot of mistakes that didn't want to admit, while at the same time trying to copy Martin's work. Sarah mediated once more. It seemed clear that Martin's attitude was scaring the sweet Vivian, and Vivian used to tell Sarah "it's like nobody here likes me... at times I feel I should quit". The copying part was justified by Sarah as "Martin, please understand that Vivian is still learning... maybe it's telling something good about you, that she's chosen to follow your line of work".

Time goes by, and after several arguments this time with Sarah, Martin requested to be transferred to another department. Sarah couldn't believe at that point Vivian's continued mistakes. She wanted to believe that youth was the answer, and she talked to her about all of them. Vivian said "I'm sorry" and excused herself in the stress caused by being under the constant attack of Martin, who obviously didn't like her. When Martin's transfer request was accepted, Vivian had a slip, "finally that moron is away from here". Sarah didn't hear it, but Leanne did.

The story repeated now with Leanne. This time, Sarah began being more wary about Vivian. She also noticed a detail that scared her: Vivian was dressing exactly like her. Vivian noticed Sarah's wariness. Before Sarah had time to see it coming, for she was always busy either working or covering someone else's back, her bosses notified her of a complaint. According to that complaint, her behaviour was the cause of the many disputes happening in the last months in the company. They said having investigated it, and taken the decision of sending her home for a couple of days so she could "relax and focus again in the company's interests".

Sarah couldn't believe it. While she was at home, Leanne called her. "She's using your projects telling everybody she came up with them. She's not even waited for your second day's absence. Now tell me again she's a sweet person." Sarah realized she had been Vivian's target from the first day. Now it would be impossible for her to explain to her bosses what happened, since it was her, Sarah, who defended Vivian when other colleagues had issues with her, trying to be fair to the fact that Vivian was "young and lacking experience".

She decided to quit. The colleagues, although didn't want to confront the bosses, also decided to turn their backs to Vivian, as a protest to Sarah's quitting. Vivian couldn't use anyone anymore to blame because of her mistakes, and was eventually fired. Sarah never received an apology call.


Now this case is more subtle. Leanne and Martin's normal attitude made it difficult to realize that Vivian was jealous and needed the praise and the attention.

It's even more difficult to spot abuse when it consists of an accumulation of "often disdain in small doses, disguised as valid criticism" (what I call at times "the water drop technique" - A water drop alone does nothing. But one after the other fill a bucket and the bucket eventually overflows.)

For the abused, it's evident what's going on. But for everybody else, the abused seems to be obsessed about the abuser. To the eyes of everybody else, the abused looks like the abuser, like a person unable of admitting criticism and thus attacking the critic. They will not see anything weird in those "small doses", and because they are "small", when the abused tries to explain, everybody else says "oh come on, such a big deal over that little thing?" The abused is portrayed like someone overreacting, and nobody takes you seriously then. Everybody is collaborating with your abuser, by denying the abuse is happening, by denying even a slight consideration to the possibility. And it seems like the right and rational thing to do. The abuser knows, and takes advantage from it.


Something that seems to be a "common denominator" in all these stories is that seen from outside, you can't believe that people allowed to be so easily manipulated. For example, in Norman's case, people at the office could have chosen not favoring the investigation, but not attacking him either. They did. They did out of fear, and what they feared, happened anyway. Sarah should have realized earlier what Vivian was about, but Leanne and Martin's attitude made her think it was all a matter of jealousy. And what to say about the "water drop falling again and again" kind of abuse?

My conclusion here is that abuse seems clear from outside and once it happened and all is over. But while it's happening, and specially if you're one of the people involved (abused, abuser's pawn, etc.)... it doesn't seem so easy to tell. Now, how do you feel about? You keep thinking that spotting abuse, and so being empathetic, is so easy? Good luck in your life if the answer is a definite "yes".

IMAGE: Sweet Snakes. Are you sure that you can really tell who they are?, in Flickr.