Files
mips/src/common/jman/grid.c
T
jens 2c4a6af07b - refactored common sources into common
git-svn-id: http://moon:8086/svn/mips@197 a8ebac50-d88d-4704-bea3-6648445a41b3
2021-11-23 17:43:37 +00:00

414 lines
9.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <jman/ri.h>
#include <jman/types.h>
#include <jman/matrix.h>
#include <jman/linklist.h>
#include <jman/vars.h>
#include <jman/grid.h>
#include <jman/graph_state.h>
#include <jman/object.h>
void Grid_create(grid_t *pObj, uint32_t npu, uint32_t npv)
{
uint32_t i, j, k, nu, nv;
ri_var_t *pVar;
nu = npu + 1;
nv = npv + 1;
pObj->nu = nu;
pObj->nv = nv;
pObj->npoints = nu*nv;
VarListInit(&pObj->vars);
pObj->pPointPos = (pixelpos_t*)malloc(nu*nv*sizeof(pixelpos_t));
memset(pObj->pPointPos, 0, nu*nv*sizeof(pixelpos_t));
pObj->pPointState = (point_state_t*)malloc(nu*nv*sizeof(point_state_t));
memset(pObj->pPointState, 0, nu*nv*sizeof(point_state_t));
k=0;
for (i=0; i < nv; i++)
{
for (j=0; j < nu; j++)
{
pObj->pPointPos[k][0] = j;
pObj->pPointPos[k][1] = i;
k++;
}
}
for (i=0; i < (nv-1)*nu; i += nu)
{
for (j=0; j < nu-1; j++)
{
pObj->pPointState[i+j].has_face = 1;
}
}
for (i=0; i < pObj->npoints; i ++)
{
pObj->pPointState[i].visible = 1;
}
}
void Grid_free(grid_t *pObj)
{
if (pObj->pPointPos)
free(pObj->pPointPos);
if (pObj->pPointState)
free(pObj->pPointState);
// VarListDelByName(&pObj->vars, "P");
// VarListPrint(&pObj->vars);
VarListFree(&pObj->vars);
}
void Grid_CopyVarByName(grid_t *pObj, RtToken pDstName, RtToken pSrcName)
{
ri_var_t *pSrc, *pDst;
RtPointer pSrcData, pDstData;
pSrc = VarListFindByName(&pObj->vars, pSrcName);
pDst = VarListFindByName(&pObj->vars, pDstName);
if (pDst)
{
if (pSrc->etype != pDst->etype)
{
fprintf(stderr, "Grid_CopyVar(): Variables are not of same type!\n");
return;
}
if (pSrc->nvalues != pDst->nvalues)
{
fprintf(stderr, "Grid_CopyVar(): Variables are not of same size!\n");
return;
}
}
else
{
pDst = VarListDeclare(&pObj->vars, pDstName, pSrc->cls, pSrc->type);
VarAlloc(pDst, pSrc->nvalues);
}
pSrcData = VarGet(pSrc);
pDstData = VarGet(pDst);
memcpy(pDstData, pSrcData, pSrc->value_size*pSrc->nvalues);
}
void Grid_InitUV(grid_t *pObj)
{
uint32_t i, j, k, nu, nv;
RtFloat *pU, *pV, u, v, du, dv;
ri_var_t *pVar;
nu = pObj->nu;
nv = pObj->nv;
du = (RtFloat)1/(nu-1);
dv = (RtFloat)1/(nv-1);
pVar = VarListDeclare(&pObj->vars, "u", "varying", "float");
pU = (RtFloat*)VarAlloc(pVar, nu*nv);
pVar = VarListDeclare(&pObj->vars, "v", "varying", "float");
pV = (RtFloat*)VarAlloc(pVar, nu*nv);
pVar = VarListDeclare(&pObj->vars, "du", "uniform", "float");
VarSet(pVar, (RtPointer)&du, 1);
pVar = VarListDeclare(&pObj->vars, "dv", "uniform", "float");
VarSet(pVar, (RtPointer)&dv, 1);
// Init uv-coords
k = 0;
v = 0;
for (i=0; i < nv; i++)
{
u = 0;
for (j=0; j < nu; j++)
{
pU[k] = u;
pV[k] = v;
u += du;
k++;
}
v += dv;
}
}
void Grid_assign_derivs(grid_t *pObj)
{
uint32_t i, j, k, nu, nv;
RtPoint *pPoint, *pDPDU, *pDPDV, dpd2;
RtFloat du, dv, ik;
ri_var_t *pVar;
nu = pObj->nu;
nv = pObj->nv;
pPoint = (RtPoint*)VarGetByName(&pObj->vars, "P");
du = *((RtFloat*)VarGetByName(&pObj->vars, "du"));
dv = *((RtFloat*)VarGetByName(&pObj->vars, "dv"));
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
if (!pDPDU)
pDPDU = (RtPoint*)VarAlloc(VarListDeclare(&pObj->vars, "dpdu", "varying", "point"), pObj->npoints);
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
if (!pDPDV)
pDPDV = (RtPoint*)VarAlloc(VarListDeclare(&pObj->vars, "dpdv", "varying", "point"), pObj->npoints);
for (i=0; i < pObj->npoints; i += nu)
{
for (j=0; j < nu-1; j++)
{
ik = (RtFloat)1/du;
for (k=0; k < 3; k++)
{
pDPDU[i+j][k] = ik*(pPoint[i+j+1][k] - pPoint[i+j][k]);
}
}
for (k=0; k < 3; k++)
{
pDPDU[i+j][k] = 2*pDPDU[i+j-1][k] - pDPDU[i+j-2][k];
}
}
for (i=0; i < nu; i++)
{
for (j=0; j < (nv-1)*nu; j += nu)
{
ik = (RtFloat)1/dv;
for (k=0; k < 3; k++)
{
pDPDV[i+j][k] = ik*(pPoint[i+j+nu][k] - pPoint[i+j][k]);
}
}
for (k=0; k < 3; k++)
{
pDPDV[i+j][k] = 2*pDPDV[i+j-nu][k] - pDPDV[i+j-2*nu][k];
}
}
}
void Grid_calc_normal(grid_t *pObj, RtToken name)
{
uint32_t i;
RtFloat *a, *b;
RtPoint *pPoint, *pDPDU, *pDPDV, *pN;
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
pN = (RtPoint*)VarGetByName(&pObj->vars, name);
if (!pN)
pN = (RtPoint*)VarAlloc(VarListDeclare(&pObj->vars, name, "varying", "point"), pObj->npoints);
for (i=0; i < pObj->npoints; i++)
{
a = pDPDU[i];
b = pDPDV[i];
pN[i][0] = a[1]*b[2] - a[2]*b[1];
pN[i][1] = a[2]*b[0] - a[0]*b[2];
pN[i][2] = a[0]*b[1] - a[1]*b[0];
}
}
void Grid_displace(grid_t *pObj)
{
uint32_t i, j, k;
RtPoint *pP, *pDPDU, *pDPDV, *pN;
RtColor *pCs, *pCi;
RtFloat *pU, *pV, fd, kn, kd;
pP = (RtPoint*)VarGetByName(&pObj->vars, "P");
pU = (RtFloat*)VarGetByName(&pObj->vars, "u");
pV = (RtFloat*)VarGetByName(&pObj->vars, "v");
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
pN = (RtPoint*)VarGetByName(&pObj->vars, "Ng");
kd = 0.00;
for (i=0; i < pObj->npoints; i++)
{
if (!pObj->pPointState[i].visible)
continue;
kn = (RtFloat)1/Norm((RtFloat*)pN[i], 3);
fd = cos(10*3.141592654*pV[i]);
pP[i][0] += kd*fd*pN[i][0]*kn;
pP[i][1] += kd*fd*pN[i][1]*kn;
pP[i][2] += kd*fd*pN[i][2]*kn;
}
Grid_assign_derivs(pObj);
Grid_calc_normal(pObj, "Ng");
}
void Normalize(RtPoint N, RtPoint Nn)
{
RtFloat k;
k = (RtFloat)1/Norm((RtFloat*)N, 3);
Nn[0] = N[0]*k;
Nn[1] = N[1]*k;
Nn[2] = N[2]*k;
}
void Negate(RtPoint N, RtPoint Ni)
{
Ni[0] = -N[0];
Ni[1] = -N[1];
Ni[2] = -N[2];
}
RtFloat* Diffuse(linkedlist_t *pLightList, RtPoint N, RtPoint P)
{
static RtFloat result[3];
RtPoint L, Ln, Nn;
linkedlist_t *pLights;
object_t *pLight;
RtFloat k, kn;
pLights = LinkedList_find_first(pLightList);
memset(result, 0, sizeof(RtColor));
Normalize(N, Nn);
while(pLights)
{
pLight = (object_t*)LinkedList_get(pLights);
L[0] = (*pLight->pXform)[0][3] - P[0];
L[1] = (*pLight->pXform)[1][3] - P[1];
L[2] = (*pLight->pXform)[2][3] - P[2];
Normalize(L, Ln);
k = MAX(ScalarProduct(Ln, Nn, 3), 0);
result[0] += pLight->pAttr->cs[0] * k;
result[1] += pLight->pAttr->cs[1] * k;
result[2] += pLight->pAttr->cs[2] * k;
pLights = pLights->pNext;
}
return result;
}
RtFloat* Specular(linkedlist_t *pLightList, RtPoint N, RtPoint P, RtPoint I, RtFloat roughness)
{
static RtFloat result[3];
RtPoint L, H, Hn, Ln, Nn, In, Ini;
linkedlist_t *pLights;
object_t *pLight;
RtFloat k, kn;
pLights = LinkedList_find_first(pLightList);
memset(result, 0, sizeof(RtColor));
Normalize(N, Nn);
Normalize(I, In);
Negate(In, Ini);
while(pLights)
{
pLight = (object_t*)LinkedList_get(pLights);
L[0] = (*pLight->pXform)[0][3] - P[0];
L[1] = (*pLight->pXform)[1][3] - P[1];
L[2] = (*pLight->pXform)[2][3] - P[2];
Normalize(L, Ln);
H[0] = Ini[0] + Ln[0];
H[1] = Ini[1] + Ln[1];
H[2] = Ini[2] + Ln[2];
Normalize(H, Hn);
k = pow(MAX(ScalarProduct(Nn, Hn, 3), 0), (RtFloat)1/roughness);
result[0] += pLight->pAttr->cs[0] * k;
result[1] += pLight->pAttr->cs[1] * k;
result[2] += pLight->pAttr->cs[2] * k;
pLights = pLights->pNext;
}
return result;
}
void Grid_shade(grid_t *pObj, RtMatrix *pXform, linkedlist_t *pLights)
{
uint32_t i, j, k;
RtPoint *pP, *pDPDU, *pDPDV, *pN, *pI;
RtColor *pCs, *pCi;
RtFloat *pU, *pV, fd, kn, vt, p[4], d[4], *pCl_diff, *pCl_spec;
RtFloat kd, ks;
pP = (RtPoint*)VarGetByName(&pObj->vars, "P");
pU = (RtFloat*)VarGetByName(&pObj->vars, "u");
pV = (RtFloat*)VarGetByName(&pObj->vars, "v");
pCs = (RtColor*)VarGetByName(&pObj->vars, "Cs");
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
pN = (RtPoint*)VarGetByName(&pObj->vars, "Ng");
pI = (RtPoint*)VarGetByName(&pObj->vars, "I");
pCi = (RtColor*)VarAlloc(VarListDeclare(&pObj->vars, "Ci", "varying", "color"), pObj->npoints);
p[3] = (RtFloat)1.0;
kd = 1;
ks = 0.4;
for (i=0; i < pObj->npoints; i++)
{
if (!pObj->pPointState[i].visible)
continue;
pCl_diff = Diffuse(pLights, pN[i], pP[i]);
pCl_spec = Specular(pLights, pN[i], pP[i], pI[i], 0.01);
fd = (RtFloat)rand()/RAND_MAX;
pCi[i][0] = (*pCs)[0]*(kd*pCl_diff[0]) + ks*pCl_spec[0];
pCi[i][1] = (*pCs)[1]*(kd*pCl_diff[1]) + ks*pCl_spec[1];
pCi[i][2] = (*pCs)[2]*(kd*pCl_diff[2]) + ks*pCl_spec[2];
}
}
void Grid_shadeConstant(grid_t *pObj)
{
uint32_t i;
RtColor *pCs, *pCi;
pCs = (RtColor*)VarGetByName(&pObj->vars, "Cs");
pCi = (RtColor*)VarAlloc(VarListDeclare(&pObj->vars, "Ci", "varying", "color"), pObj->npoints);
for (i=0; i < pObj->npoints; i++)
{
if (!pObj->pPointState[i].visible)
continue;
pCi[i][0] = (*pCs)[0];
pCi[i][1] = (*pCs)[1];
pCi[i][2] = (*pCs)[2];
}
}